How do i get data ouside of "post" function? - express

so i an have express server, and i want to use data that I get outside of post function or in other post functions here is the code
app.post('/bg-login', (req, res) => {
var user;
req.body.email;
req.body.password;
var email1 = req.body.email;
const path = './Databases/User/' + email1 + '.json';
if (fs.existsSync(path)) {
try {
// Note that jsonString will be a <Buffer> since we did not specify an
// encoding type for the file. But it'll still work because JSON.parse() will
// use <Buffer>.toString().
} catch (err) {
return;
}
var user1 = fs.readFileSync('./Databases/User/1.json');
var user = JSON.parse(user1)
} else {
res.redirect("/login-e1");
}
console.log(user);
Error: user is not defined, so how could I get this variable ( user) to work outside POST function

You can just define the variable "user" in the global scope instead of the function scope.

Related

express deprecated res.send(status, body): Use res.status(status).send(body) instead

is anything I am doing wrong because I am new to this, I got express deprecated res.send(status, body): Use res.status(status).send(body) instead error when I carry out the update operation using PUT in postman.
router.put("/admin/update_profile/:id", async (req, res) => {
try {
const id = req.params.id;
const updatedData = req.body;
const options = { new: true };
const result = await SomeModel.findByIdAndUpdate(id, updatedData, options);
res.send(result);
// res.status(200).send(result)
} catch (err) {
res.send("Error ", err);
// res.status(404).send("Error ", err)
}
});
Pretty Much what the error says. Express has deprecated res.send(status, body);.
Replace that line with res.status(status).send(body);
Please note that writing only res.send(body); will send a status of 200 by default, so remember to use .status() in failure cases.
res.send("Error ", err);
You're passing two parameters to res.send() which as the warning message indicates is deprecated but still supported.
It's interpreting the string literal "Error " as a response status code which is not valid.
You should only pass a single parameter to send() and set the status via status()
res.status(500).send(err);
router.put("/admin/update_profile/:id", async (req, res) => {
try {
const id = req.params.id;
const updatedData = req.body;
const options = { new: true };
const result = await SomeModel.findByIdAndUpdate(id.trim(), updatedData,
options);
res.status(200).send(result);
} catch (err) {
res.status(404).send(err);
}
});

mongoose save by reference multiple document

I'd like to make new document by reference of two documents.
**app.post('/student_badge/register', async (req, res) => {
const name = req.body.name;
const category = req.body.category;
People.find({name: name}, '_id', function (err, doc) {
if (err) return handleError(err);
var obj = eval(doc);
id = obj[0]._id;
})
Badge.find({category: category}, 'points title', function (err, doc) {
if (err) return handleError(err);
var obj2 = eval(doc);
points = obj2[0].points;
title = obj2[0].title;
console.log(title + " " + points);
});
data = {
id: id,
title: title,
points: points
}
console.log("data: " + data);
const sbadge = new StudentBadge(data);
sbadge.
save()
.then(result => {
res.status(201).json({
message: 'Post created successfully!',
post: result
});
})
.catch(err => {
console.log(err);
});
});**
But I cannot call three variables like id, title, points to store them in 'data'.
How can I call variables?
Thanks
Your code does not work because the variables you are trying to access, i.e. id, title, points, are being set on a callback function that gets executed asynchronously.
I would suggest using async/await instead of callbacks so that you can thereafter use the data from the other documents you are querying in the same function. In addition, I suggest to use findOne() since you only access the first entry in db.
Something like the example below should work: (I have abstracted the middleware in a separate function for clarity to use with express)
const createStudentBadge = async (req, res, next) => {
const {name, category} = req.body;
let person, badge;
try {
person = await Person.findOne({name}); // shortcut for {name: name}
badge = await Badge.findOne({category});
} catch(err) {
// handle error
}
if (!person || !badge) {
// Handle case where no document has been found in db
// This case will not throw an error when calling find()
}
data = {
id: person._id,
title: badge.title,
points: badge.points
}
const studentBadge = new StudentBadge(data);
try {
await studentBadge.save();
} catch(err) {
// handle error
}
res.status(201).json({
message: 'Post created successfully!',
post: studentBadge
});
}
app.post('/student_badge/register', createStudentBadge);
If you wanted to perform the querying in parallel, you could make use of Promise.all() and run both queries at the same time. More info can be found at MDN documentation

Converting Url parameters to object id

How can Id gotten from request parameter in express be converted to object id for Mongoose
Let's say for instance
app("path/get_user_b
yid/:id6888",(req,
res)=>.{
//code to convert I'd
back to object...
}
you can call findById function to get a specific user as bellow
const mongoose = require('mongoose');
connst Schema = mongoose.Schema;
const User = new Schema({
name: String,
...
// other data
});
app.get('path/get_user_b yid/:id', (req, res) => {
cosnt id = req.params.id;
User.findById(id, function (err, user) {
if (err) {
return res.status(500);
}
return res.status(200).json(user);
});
});

Use updated req variable in middleware after route execution

I have a middleware function I wrote to perform some logging for each HTTP request that comes in
export const winstonMiddlewareLogger = (req: express.Request, res: express.Response, next: express.NextFunction) => {
let _startTime = new Date();
res.on("finish", function() {
let responseTime = new Date().getTime() - _startTime.getTime() + "ms";
let method = req.method;
let url = req.originalUrl;
let body = req.body ? req.body : {};
let query = req.query;
let params = req.params;
let status = res.statusCode;
let msg = `HTTP ${req.method} ${req.url} ${responseTime}`;
let logDocument = {
msg,
method,
url,
params,
query,
body,
status,
responseTime,
};
logger.info(undefined, logDocument)
});
next();
};
Next thing I have a route
app.post("/slow", (req, res) => {
req.testParam = "test";
res.send("hello");
});
I want to be able to access the new property of the req parameter that is initiated in the /slow (testParam), in the res.on(...){...} event listener in my middleware function the next way:
if (req.hasOwnProperty('testParam')) {
console.log(req.testParam)
}
But the current state is that the req parameter is not updated no matter what I do in the route itself, because the req parameter it knows is only the one I get at the beginning of each request.
Changing the req variable in the route doesn't change it in the middleware which has already got a req variable of its own.
Any idea how to do it?
Ok so I found winston-express which actually does the things I wanted to.
What it does is to reassign the res.end function to a function he wrote himself.
This function can access the modified objects of req and res after the route has already executed.
So for the sake of showing how it works, I change my route to:
app.get("/", (req, res) => {
req._attributeFromRoute = "test";
res.send("hello");
});
And my middleware function looks something like this:
export const winstonMiddlewareLogger2 = (req: express.Request, res: express.Response, next: express.NextFunction) => {
let _startTime = new Date();
let end = res.end;
res.end = (chunk: any, encoding: string, cb?: () => void): void => {
res.end = end;
res.end(chunk, encoding, cb);
console.log(req._attributeFromRoute) // Notice that this property was not declared before the route execution, and now we can access it after it was defined
let responseTime = new Date().getTime() - _startTime.getTime() + "ms";
let method = req.method;
let url = req.originalUrl;
let body = req.body ? req.body : {};
let query = req.query;
let params = req.params;
let status = res.statusCode;
let msg = `HTTP ${req.method} ${req.url} ${responseTime}`;
let logDocument = {
msg,
method,
url,
params,
query,
body,
status,
responseTime,
};
logger.info(undefined, logDocument)
};
next();
};
And the way it will work is that the middleware function will wait for the route to execute and call the req.end function, which will enter the end function we created ourselfs.
We will then execute the original end function that had as a reference in the end variable.
Then we can do whatever we want with the updated objects of req and res.

Using Express.js's res.send() with async.each

async1.each(arr, function(arrayMember) {
orders.where('name', arrayMember).fetch({withRelated: ['allOrders']}).
then(function(dd2, callback) {
dd2 = dd2.toJSON();
var sendMemberOrder = {};
sendMemberOrder.name = dd2.name;
sendMemberOrder.lastOrder = dd2.allOrders.length;
res.send(sendMemberOrder);
});
}, function(err) {
if (err) {
console.log("err");
}
});
I'm trying to use Express's res.send() feature but given that I'm using async.each, I'm getting
headers already sent
error.
How can I pass the result of each iteration as an array when a request is being made?
Since you already use promises here, I would like to doscourage you from using async.js here. Your code is broken anyway as it does not call callback at all, and the callback parameter is declared on the wrong function. Instead you could try this:
app.get(your_route, function(req, res, next) {
// obtain arr
Promise.all(arr.map(function(arrayMember) {
return orders.where('name', arrayMember)
.fetch({withRelated: ['allOrders']})
.then(function(dd2) {
dd2 = dd2.toJSON();
return {
name: dd2.name,
lastOrder: dd2.allOrders.length
};
});
})).then(function(resultData) {
res.send(resultData);
}).catch(function(err) {
console.log(err);
next(err);
});
});