I'm working on a Vue frontend/Express backend application and am having an issue with a numbers in a JSON response 'arriving' at the frontend as null.
server:
db.boards.getUserBoards(user.user_id).then((boards) => {
let userBoards = [];
if (boards) userBoards = boards;
user.boards = userBoards;
const token = jwt.sign(JSON.stringify(user), config.secret);
res.json({ message: 'Token granted', token, user });
Where boards is an array such as:
"boards": [
{
"board_id": 1,
"name": "test"
}
]
This works fine in postman (that's where the above was directly copied from), but the response in my client application has a null value
see response. It seems to only affect the numerical values within the boards array, as the user object has an numerical id field that makes it across without issue.
client:
Axios.post(`${api}/api/stuff`, credentials)
.then(({data}) => { console.log(data) })
What am I missing?!
Related
i am trying to set some user data along with token ID in Cookie. Token is set perfectly and also in console.log output but my user JSON object is unable to set and shows me "object Object" as Cookies but my user data present in console.log. i think i am unable to convert JSON data into cookie. here is my code of nextjs and packages i use for this.
package use
js-cookies
nextjs - latest version
here is my API for user login
import db from "../../helpers/initDB";
import User from "../../models/User";
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
db.connect();
// eslint-disable-next-line import/no-anonymous-default-export
export default async (req,res)=>{
const {email,password} = req.body
try{
if(!email || !password){
return res.status(422).json({error:"All Fields Are Required"})
}
const user = await User.findOne({email})
if(!user){
return res.status(404).json({error:"user dont exists with that email"})
}
const doMatch = await bcrypt.compare(password,user.password)
if(doMatch){
const token = jwt.sign({userId:user._id},process.env.JWT_SECRET,{
expiresIn:"7d"
})
const {name,role,email} = user
res.status(201).json({token,user:{name,role,email}})
}else{
return res.status(401).json({error:"email or password dont match"})
}
}catch(err){
console.log(err)
}
}
db.disconnect();
my api is working fine and set the res.status with all my data.
here is code part where i am trying to set cookie
console.log(res2)
Cookie.set('user', res2.user);
Cookie.set('token', res2.token);
router.push('/dashboard/')
and here is my console.log output where user data and token is present
Object { token:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MWE4YzcwMGIxZmI3OWJmOGNjOWY3ZjUiLCJpYXQiOjE2Mzg1MTczODIsImV4cCI6MTYzOTEyMjE4Mn0.9T-B4c3xtsgCSGSWUMCZ_GU56FYC5VLeVDhGzAWiwjA", user: {…} }
user: Object { name: "mohit nagar", role: "user", email: "gujjarmaxx#gmail.com" }
: Object { … }
and here is my cookies
{
"Request Cookies": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MWE4YzcwMGIxZmI3OWJmOGNjOWY3ZjUiLCJpYXQiOjE2Mzg1MTY1NzcsImV4cCI6MTYzOTEyMTM3N30.PoBD03Qp-7-iN5yvnjvQfflTI5DO8z3Lqk3sMYZs0Y0",
"user": "[object Object]"
}
}
i don't know what i am doing wrong.
A value of a cookie must be a string. You can stringify your user object into JSON
Cookie.set('user', JSON.stringify(res2.user))
When you want to read your cookie you will parse the string
const user = JSON.parse(Cookie.get('user'))
i have cypress request call returning Json array
{ids:[one, two, three]}
How can i parse out one of the array values from the body of response and pass it to the next test?
Considering the given information I guess what you want is Asserting Network Calls from Cypress Tests.
There is a good example in the cypress-example-recipes
I guess you could do something like
describe('Test', () => {
let ids;
it('gets expected response', () => {
cy.server()
cy.route('GET', '/url').as('response')
cy.visit("url")
// log the request object
cy.get('#response').then(console.log)
// confirm the request status
cy.get('#response').should('have.property', 'status', 200)
// confirm the request's response
cy.get('#response').its('response').then((res) => {
expect(res.body).to.deep.equal({
"ids": ["one", "two", "three"]
})
// store the ids in a variable
ids = JSON.parse(res.body)?.ids
})
})
})
So basically I will be getting a feed of a few huge JSON files. I want to convert them into SQL and store them into a MySQL database.
The catch here is that later on I will be needing to get the SQL files from the database and convert them into JSON objects.
https://sqlizer.io/#/ Something like this, where it converts JSON to SQL but vice versa as well.
So I was wondering if there are any NodeJS modules/libraries that have this type of capability.
Thank you.
I don't see where is the problem. With most sql libraries in node, when doing queries in sql, you are getting json back or at least you are getting data that you can convert to JSON with JSON.stringify.
Let say we are doing it with knex and Postgres:
const db = require('knex')({
client: 'pg',
connection: {
host : '127.0.0.1',
user : 'your_database_user',
password : 'your_database_password',
database : 'myapp_test'
}
});
/*
Let assume the content of the json files is this way:
[
{
"name": "foo",
"last_name": "bar"
},
{
"name": "foo",
"last_name": "bar"
}
];
Schema of table should be (
name TEXT NOT NULL,
last_name TEXT NOT NULL
)
*/
// these are the files
const myFilesToRead = ['./file1.json', './file2.json'];
// we are looping through myFilesToRead
// reading the files
// running queries for each object
Promise.all(
myFilesToRead.map((file) => {
// yes you can require json files :)
const fContent = require(file);
return Promise.all(fContent.map((obj) => {
// knex is a query builder, it will convert the code below to an SQL statement
return db('table_name')
.insert(obj)
.returning('*')
.then((result) => {
console.log('inserted', result);
return result;
});
}));
})
)
.then((result) => {
// let's now get these objects back
return db('table_name')
.select('*');
})
.then((result) => {
// that's it
console.log(JSON.stringify(result));
});
If you want to read about knex, here is the doc:
http://knexjs.org/
Trying my first angular exercise. Receiving undefined value on 1st time from http post, but 2nd time getting proper response (Edge, Firefox). Thanks!
LoginService (Calls Http post method and returns observable)
login(loginRequest: LoginRequest){
console.log("LoginService.login - userName " + loginRequest.username);
let options = new RequestOptions({ headers: headers });
return this.http.post(this.http_url, loginRequest, options).map( res =>
res.json());
LoginFormComponent (calls service class and convert JSON to typescript object)
onSubmit() {
this.loginSvc.login(this.loginRequest).subscribe(
data => this.loginResponseStr = data,
error => alert(error),
() => console.log('Request completed')
);
var loginResponse = new LoginResponse();
loginResponse.fillFromJSON(JSON.stringify(this.loginResponseStr));
console.log(loginResponse.status);
console.log(loginResponse.statusDesc);
if(loginResponse.status == "SUCCESS"){
this.router.navigate(['/home-page']);
}
Console log
LoginService.login - userName admin main.bundle.js:370:9
undefined main.bundle.js:266:9
undefined main.bundle.js:267:9
Request completed main.bundle.js:263:181
LoginService.login - userName admin main.bundle.js:370:9
SUCCESS main.bundle.js:266:9
VALID USER main.bundle.js:267:9
Request completed main.bundle.js:263:181
Angular server calls are asynchronous, that mean the code wont wait for the server to respond before executing the rest of the code. Such as PHP. So you would not see a blank page waiting for the server to send data. When you want to deal with the respose come from a server call you have to add all the code within the subscribe; that means if this information needed to be passed to another service.
Your code should look like this.
onSubmit() {
this.loginSvc.login(this.loginRequest).subscribe(
data => {
this.loginResponseStr = data
var loginResponse = new LoginResponse();
loginResponse.fillFromJSON(JSON.stringify(data));
console.log(loginResponse.status);
console.log(loginResponse.statusDesc);
if (loginResponse.status == "SUCCESS") {
this.router.navigate(['/home-page']);
}
},
error => alert(error),
() => console.log('Request completed')
);
}
Im using express, body-parser and moongose to build a RESTful web service with Node.js. Im getting json data in the body of a POST request, that function looks like this:
router.route('/match')
// create a match (accessed at POST http://localhost:3000/api/match)
.post(function(req, res) {
if (req._body == true && req.is('application/json') == 'application/json' ) {
var match = new Match(); // create a new instance of the match model
match.name = req.body.name; // set the match name and so on...
match.host = req.body.host;
match.clients = req.body.clients;
match.status = req.body.status;
// save the match and check for errors
match.save(function(err) {
if (err) {
//res.send(err);
res.json({ status: 'ERROR' });
} else {
res.json({ status: 'OK', Match_ID: match._id });
}
});
} else {
res.json({ status: 'ERROR', msg: 'not application/json type'});
}
});
The model Im using for storing a match in the database looks like this:
// app/models/match.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MatchSchema = new Schema({
name: String,
host: String,
clients: { type: [String]},
date: { type: Date, default: Date.now },
status: { type: String, default: 'started' }
});
module.exports = mongoose.model('Match', MatchSchema);
But how do I validate that the json data in the body of the POST request has the key/value fields I want? For clarification, I dont want to insert data in the database that is incomplete. If I test to skip a key/value pair in the json data I get a missing field in the database and when I tries to read req.body.MISSING_FIELD parameter in my code I get undefined. All fields except date in the model is required.
Im using json strings like this to add matches in the database
{"name": "SOCCER", "host": "HOST_ID1", "clients": ["CLIENT_ID1", "CLIENT_ID2"], "status": "started"}
I use a very simple function that takes an array of keys, then loops through it and ensures that req.body[key] is not a falsy value. It is trivial to modify it to accommodate only undefined values however.
In app.js
app.use( (req, res, next ) => {
req.require = ( keys = [] ) => {
keys.forEach( key => {
// NOTE: This will throw an error for ALL falsy values.
// if this is not the desired outcome, use
// if( typeof req.body[key] === "undefined" )
if( !req.body[key] )
throw new Error( "Missing required fields" );
})
}
})
in your route handler
try{
// Immediately throws an error if the provided keys are not in req.body
req.require( [ "requiredKey1", "requiredKey2" ] );
// Other code, typically async/await for simplicity
} catch( e ){
//Handle errors, or
next( e ); // Use the error-handling middleware defined in app.js
}
This only checks to ensure that the body contains the specified keys. IT won't validate the data sent in any meaningful way. This is fine for my use case because if the data is totally borked then I'll just handle the error in the catch block and throw an HTTP error code back at the client. (consider sending a meaningful payload as well)
If you want to validate the data in a more sophisticated way, (like, say, ensuring that an email is the correct format, etc) you might want to look into a validation middle-ware, like https://express-validator.github.io/docs/