I am getting a 500 response. Is the way I am trying this wrong? Or is there something I'm missing? - node.js

I'm making a game project. I have everything working to where you can create a character, and it posts okay to the database, and I can see the characters I've created on an endpoint with all the details included.
Where it doesn't work anywhere else is where I have things shifted from a context state to a separate context state for a 'character sheet' state. All the data successfully goes to my character sheet, and console.logs support everything is properly showing up, but it won't post to my url.
My model:
const mongoose = require("mongoose"),
Schema = mongoose.Schema;
const characterSheetSchema = new Schema({
characterPowers: {},
characterInventory: {},
characterArmor: {},
characterShield: {},
characterWeapon: {},
characterCoin: {},
characterHp: {},
characterStats: {},
characterExperience: { type: Number },
characterRace: {},
characterClass: {},
characterAge: {
type: Number,
},
characterName: {
type: String,
},
characterDescription: {
type: String,
},
characterLevel: { type: Number },
});
module.exports = CharacterSheet = mongoose.model(
"charactersheet",
characterSheetSchema
);
My routes:
const router = require('express').Router()
const CharacterSheet = require('../../models/chracterSheet/characterSheet.model')
router.post("/createcharactersheet", (req, res) => {
try {
let {
characterPowers,
characterInventory,
characterArmor,
characterShield,
characterWeapon,
characterCoin,
characterHp,
characterStats,
characterExperience,
characterRace,
characterClass,
characterAge,
characterName,
characterDescription,
characterLevel
} = req.body
const newCharacterSheet = new CharacterSheet({
characterPowers,
characterInventory,
characterArmor,
characterShield,
characterWeapon,
characterCoin,
characterHp,
characterStats,
characterExperience,
characterRace,
characterClass,
characterAge,
characterName,
characterDescription,
characterLevel
})
const savedCharacterSheet = newCharacterSheet.save()
res.json(savedCharacterSheet)
} catch (err) {
res.status(500).json({err: err.message})
}
})
router.get('/viewcharactersheets', (req, res) => {
CharacterSheet.find({}, function(err, charactersheets) {
if (err) {
console.log(err)
} else {
return res.json({charactersheets: charactersheets})
}
})
})
module.exports = router
My post request:
Axios.post("http://localhost:5000/characters/createcharactersheet", {
characterPowers: characterSheet.characterPowers,
characterInventory: characterSheet.characterInventory,
characterArmor: characterSheet.characterArmor,
characterShield: characterSheet.characterShield,
characterWeapon: characterSheet.characterWeapon,
chacterCoin: characterSheet.characterCoin,
characterHp: characterSheet.characterHp,
characterStats: characterSheet.characterStats,
characterExperience: characterSheet.characterExperience,
characterRace: characterSheet.characterRace,
characterClass: characterSheet.characterClass,
characterAge: characterSheet.characterAge,
characterName: characterSheet.characterName,
characterDescription: characterSheet.characterDescription,
characterLevel: characterSheet.characterLevel,
});
My Terminal
My error
POST error
Uncaught in promise error
Everything else works and goes into my restful api, but for a reason unknown to me, it won't post to my createcharactersheet document or api.
Any insight would be appreciated.

Mongoose Model.save() returns an Promise to try to use async/await
async/await way:
router.post("/createcharactersheet", async(req, res) => {
...
try {
const newCharacterSheet = new CharacterSheet({
...
})
await newCharacterSheet.save()
res.status(201).json(newCharacterSheet)
} catch (error) {
res.status(500).send(e.message)
{
})
or (im not sure)
const savedCharacterSheet = newCharacterSheet.save()
savedCharacterSheet
.then(saved =>
res.json(saved)
)
.catch(e =>
res.status(500).send(e.message)
)
Edit
Aslo log you errors
catch (e) {
console.error(e)
}

Related

How to create a Plaid LinkToken using Node JS?

I believe Plaid updated its createLinkToken documentation, but I can't seem to figure out what I'm doing wrong here. I'm taking a course, and here is the old code that worked in using a FirebaseFunction to create a link token with Plaid:
exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {
const customerId = context.auth.id;
const plaidClient = new plaid.Client({
clientID: functions.config().plaid.client_id,
secret: functions.config().plaid.secret,
env: plaid.environments.sandbox,
options: {
version: '2019-05-29',
},
});
return plaidClient.createLinkToken({
user: {
client_user_id: customerId,
},
client_name: "Bon Voyage",
products: ["auth"],
country_codes: ["US"],
language: "en"
}).then((apiResponse) => {
const linkToken = apiResponse.link_token;
return linkToken;
}).catch((err) => {
console.log(err);
throw new functions.https.HttpsError("internal", "Unable to create plaid link token: " + err);
});
});
I've tried a number of things. I know plaid.Client is now new.Configuration but I can't seem to figure out the rest. Any helpers?
You can see in the comments below what I've tried. I've modified the code as follows, and now receive Error status code 400.
const plaid = require('plaid');
const { Configuration, PlaidEnvironments, PlaidApi } = require("plaid");
exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {
const customerId = context.auth.uid;
const configuration = new Configuration({
basePath: PlaidEnvironments.sandbox,
baseOptions: {
headers: {
plaid_client_id: functions.config().plaid.client_id,
plaid_secret: functions.config().plaid.secret,
plaid_version: '2021-05-20'
},
},
});
const plaidClient = new PlaidApi(configuration);
return plaidClient.linkTokenCreate({
user: {
client_user_id: customerId,
},
client_name: "Bon Voyage",
products: ["auth"],
country_codes: ["US"],
language: "en"
})
.then((apiResponse) => {
const linkToken = apiResponse.data.link_token;
// const linkToken = response.link_token
return linkToken;
})
.catch((err) => {
console.log(err);
throw new functions.https.HttpsError(
"internal",
" Unable to create plaid link token: " + err
);
});
});
It's difficult to answer this question as you haven't mentioned what you've tried or what error you are experiencing. Have you reviewed the sample implementations in the docs that show how to do this, including the sample code in the Quickstart and Tiny Quickstart?
Off the top of my head, I do see that this sample code specifies an API version of 2019-05-29, which is not compatible with the latest version of the Node client library that uses new.Configuration.

Error: "Missing initializer in const declaration" plaid api create link token

I'm trying to setup the plaid api in my node.js code and I need to be able to make a request for the create_link_token. The sample code from their docs is as follows:
const request: LinkTokenCreateRequest = {
user: {
client_user_id: 'user-id',
},
client_name: 'Plaid Test App',
products: ['auth', 'transactions'],
country_codes: ['US'],
language: 'en',
webhook: 'https://sample-web-hook.com',
redirect_uri: 'https://domainname.com/oauth-page.html',
account_filters: {
depository: {
account_subtypes: ['DepositoryAccountSubtype.Checking, DepositoryAccountSubtype.Savings'],
},
},
};
try {
const response = await plaidClient.linkTokenCreate(request);
const linkToken = response.data.link_token;
} catch (error) {
// handle error
}
my code is:
app.post('/api/create_link_token', async (req, res, next) => {
const request: LinkTokenCreateRequest = {
user: {
client_user_id: 'user-id',
},
client_name: 'Plaid Test App',
products: ['auth', 'transactions'],
country_codes: ['US'],
language: 'en',
webhook: 'https://sample-web-hook.com',
redirect_uri: 'https://domainname.com/oauth-page.html',
account_filters: {
depository: {
account_subtypes: ['DepositoryAccountSubtype.Checking, DepositoryAccountSubtype.Savings'],
},
},
};
try {
const response = await plaidClient.linkTokenCreate(request);
const linkToken = response.data.link_token;
} catch(e) {
handleError(e);
}
});
Right off the bat I get the error: 'LinkTokenCreateRequest' refers to a value, but is being used as a type here. Did you mean 'typeof LinkTokenCreateRequest'?ts(2749) as a red underline underneath LinkTokenCreateRequest. Side note I've never used TS before this, but I believe I have to use it on this project because some of their components require it. If I do as they suggest and change it to typeof LinkTokenCreateRequest = {... then the red underline error goes away, however upon starting the server I get the error:
const request: typeof LinkTokenCreateRequest = {
^^^^^^^
SyntaxError: Missing initializer in const declaration
I've very confused as to how I can make this work so any suggestions would be much appreciated.

How to make kuzzle-device-manager plugin API actions works?

I successfully installed and loaded kuzzle-device-manager in the backend file:
import { Backend } from 'kuzzle';
import { DeviceManagerPlugin } from 'kuzzle-device-manager';
const app = new Backend('playground');
console.log(app.config);
const deviceManager = new DeviceManagerPlugin();
const mappings = {
updatedAt: { type: 'date' },
payloadUuid: { type: 'keyword' },
value: { type: 'float' }
}
deviceManager.devices.registerMeasure('humidity', mappings)
app.plugin.use(deviceManager)
app.start()
.then(async () => {
// Interact with Kuzzle API to create a new index if it does not already exist
console.log(' started!');
})
.catch(console.error);
But when i try to use controllers from that plugin for example device-manager/device with create action i get an error output.
Here is my "client" code in js:
const { Kuzzle, WebSocket } = require("kuzzle-sdk")
const kuzzle = new Kuzzle(
new WebSocket('KUZZLE_IP')
)
kuzzle.on('networkError', error => {
console.error('Network Error: ', error);
})
const run = async () => {
try {
// Connects to the Kuzzle server
await kuzzle.connect();
// Creates an index
const result = await kuzzle.query({
index: "nyc-open-data",
controller: "device-manager/device",
action: "create",
body: {
model: "model-1234",
reference: "reference-1234"
}
}, {
queuable: false
})
console.log(result)
} catch (error) {
console.error(error.message);
} finally {
kuzzle.disconnect();
}
};
run();
And the result log:
API action "device-manager/device":"create" not found
Note: The nyc-open-data index exists and is empty.
We apologize for this mistake in the documentation, the device-manager/device:create method is not available because the plugin is using auto-provisioning until the v2.
You should send a payload to your decoder, the plugin will automatically provision the device if it does not exists https://docs.kuzzle.io/official-plugins/device-manager/1/guides/decoders/#receive-payloads

Best way to access data in react

PROBLEM:
I have a MERN application that is has a model with a couple of other models in it. The problem that I figured out later is that it saves the _id of the object and not the actual object in the model when you do this
const checkoutHistory = new Schema({
book: { type: mongoose.Schema.Types.ObjectId, ref: 'books',required: true },
checkoutCopiesNum: {type: Number, required: true},
profChosen: { type: mongoose.Schema.Types.ObjectId, ref: 'prof', required: true },
dueDate: {type: String, required: true}
})
The book: part of the object when retreived will be an id some string like "DKKLDFJhdkghhe839kdd" whatever. This is fine because then I guess I can make an API call in the react app later to search for this book. Is this the correct way to do it though?
The other way that I thought of was in the actual endpoint that retrieves the data was to call the findByID functions and set that data. It didn't work though here is the code for that:
const checkoutHistoryMiddle = async (req, res, next) => {
try {
//get the body of the request
const body = req.body
//check for data
if(!body){
return res.status(400).json({
success: false,
error: 'no body given'
})
}
const history = new CheckoutHist(body)
console.log(history)
// await Book.findById({_id: history.book}, (err, book) => {
// history.book = book
// })
// await Prof.findById({_id: history.profChosen}, (err, prof) => history.profChosen = prof)
console.log(history)
history.save().then(() => next()).catch(error => {
return res.status(400).json({
success: false,
message: error,
msg: "checkout save failed"
})
})
} catch (error) {
res.status(400).json({
success: false,
message: error,
msg: "checkoutHist failed"
})
}
}
I commented out the part I was talking about because well, it didn't work. It still saved the id instead of the object. Which like I said is fine. I gave my other idea a go and decided to do the calls inside the react app.
So I first got the array of objects from the schema provided above like this:
const [bookHist, setBookHist] = useState()
useEffect( () => {
const getHistory = async () => {
api.getCheckoutHist().then(hist => {
setBookHist(hist.data.data.filter((data) => data.book === props.book_id))
})
}
getHistory()
}, [])
This will create an array of objects in bookHist that looks like this
[{_id: "DKJFDKJDKLFJSL", book: "LDKhgajgahgelkji8440skg", checkoutCopiesNum: 3, profChosen: "gjellkdh39gh39kal930alkdfj", dueDate: "11/11/11"}, {...}]
so the next step would be to take each item in the array and get the id to search the database with so api.findProfByID(bookHist[0].profChosen)
then I would need to update the state of bookHist somehow only that item without effect the other items in the array.
The questions I have are what is the best way to update one item in the array state?
How do I make so many api calls? how do I make sure that they are waited on so that the state actually changes once the calls complete?
Here are things I have tried so far:
useEffect(() => {
bookHist.map(async bHist => {
await Axios.get("http://localhost:8174/user/professor/" + bHist.profChosen).then(async prof => {
// console.log(prof)
// console.log(prof)
bHist.profChosen = prof.data.data
// setBookHist(prevStat => ({}))
// setBookHist(...bookHist, [bookHist.])
})
setBookHist(bHist)
})
}, [])
this didn't work I assume because it would not update the state because it is not waiting on the map to finish before it sets the state of bookHist
So then I searched on the internet and found a promisAll method in react like this:
useEffect(() => {
const change = async () => {
if(bookHist){
console.log("prof")
//get the prof data
// const galleries = []
await Promise.all(bookHist.map( (bHist, index) => {
return await Axios.get("http://localhost:8174/user/professor/" + bHist.profChosen);
})).then(someData => {
console.log(someData)
});
}
change()
}, [])
This also does not work for unknown reasons. It only works if it hot reloads and does not refresh. The logging actually logs something when it hot refreshes.
here is the entirety of the funcitional component:
import React, {useState, useEffect} from 'react'
import api from '../../api/index'
import Axios from 'axios'
export default function CheckoutBookHistroy(props){
const [bookHist, setBookHist] = useState()
const [histData, setHistData] = useState([{
book: {},
prof: {}
}])
useEffect( () => {
const getHistory = async () => {
api.getCheckoutHist().then(hist => {
setBookHist(hist.data.data.filter((data) => data.book === props.book_id))
})
}
getHistory()
}, [])
//i also tried this way but this resulted in an infinite loop
const [profChosen, setProfChosen] = useState()
const handleProfFind = async (id) => {
await Axios.get("http://localhost:8174/user/professor/" + id).then(prof => {
setProfChosen(prof.data.data)
})
}
return (
<div>
{
bookHist ?
bookHist.map(data => {
//need to present the prof data here for each data obj
return (
<div>Checked out {data.checkoutCopiesNum}</div>
)}) : <div>no data</div>
}
</div>
)
}
I really hope I can gain some insight into the correct way to do all of this. I must be either really close or awfully wrong. Thank you in advance!
just by looking at your code, i don't see too much issue, although your code is a bit convoluted.
some functions has no caller, ex. handleProfFind. One suggestion, if you want to do something, just do it, no need that many functions, ex.
// assume you only want to do it once after mounting
useEffect( () => {
if (!data) {
api.getCheckoutHist().then(hist => {
// you can set your data state here
// or you can get the id inside each item, and then call more APIs
// whatever you want to do, please finish it here
}
}
}, [])

Why Hook is called in all update services methods

I'm create a hook file with the following information, which is Hooks.js
Hooks.js is working to authenticate an actions with JWT when need it, I dont need it in all servies calls.
As my understanding the syntax to call a hook was app/use route/hooks and those hooks were only applied to and specific route and not globally.
module.exports = {
errorHandler: (context) => {
if (context.error) {
context.error.stack = null;
return context;
}
},
isValidToken: (context) => {
const token = context.params.headers.authorization;
const payload = Auth.validateToken(token);
console.log(payload);
if(payload !== "Invalid" && payload !== "No Token Provided"){
context.data = payload._id;
}
else {
throw new errors.NotAuthenticated('Authentication Error Token');
}
},
isValidDomain: (context) => {
if (
config.DOMAINS_WHITE_LIST.includes(
context.params.headers.origin || context.params.headers.host
)
) {
return context;
}
throw new errors.NotAuthenticated("Not Authenticated Domain");
},
normalizedId: (context) => {
context.id = context.id || context.params.route.id;
},
normalizedCode: (context) => {
context.id = context.params.route.code;
},
};
Then I create a file for services and routes, like the following:
const Hooks = require("../../Hooks/Hooks");
const userServices = require("./user.services");
module.exports = (app) => {
app
.use("/users", {
find: userServices.find,
create: userServices.createUser,
})
.hooks({
before: {
find: [Hooks.isValidDomain],
create: [Hooks.isValidDomain],
},
});
app
.use("/users/:code/validate", {
update: userServices.validateCode,
})
.hooks({
before: {
update: [Hooks.isValidDomain, Hooks.normalizedCode],
},
});
app
.use("/users/personal", {
update: userServices.personalInfo,
})
.hooks({
before: {
update: [Hooks.isValidDomain, Hooks.isValidToken],
},
});
};
Why Hooks.isValidToken applies to all my update methods? Even if I'm not calling it?
Please help.
app.hooks registers an application level hook which runs for all services. If you only want it for a specific service and method it needs to be app.service('users').hooks().

Resources