Add data to session in nodejs express in a callback - javascript

In the below code i'm trying to fetch the user details from DB and save it to session. But unfortunately it doesn't work as i've expected, the data is not written into the session variable. I guess it's because of pass by value? Any workaround
exports.check = function(req,res,next){
..
..
getUserFromDB(req);
}
function getUserFromDB(req){
..
db.findOne(query,function(doc){
req.session.user = doc;
})
}

I think you are missing the callback call.
Are you using express and mongodb? We should post full working examples :)
exports.check = function (req, res, next) {
getUserFromDB(req, next);
};
function getUserFromDB(req, callback) {
db.findOne({ _id: req.qs.id }, function (err, doc) {
req.session.user = doc;
callback(err);
});
}

Also check for err, and also for null doc (not found).

Related

updated a document with express

I'm trying to use the mongoDB and update the status of a current document. My backend is receiving the routes my mongoDB update isn't going through.
router.post('/orders_drivers', function (req, res, next) {
console.log(req.body);
Order.update({_id:objectId(req.body.id)}, {$set: {driver:req.body.driver, driverReq:false}}).then (function (order) {
console.log('UPDATE new driver');
}).catch (next)
});
when I log the req.body, the ID I receive and the new $set parameters are correct, but the command never goes through. Any suggestions? I don't receive any errors either which I think is strange.
Mongo version is v4.0.2
I have many other routes that all work correctly.
There is no version issue. you are calling then function on non promiseable value.
You need to call a callback function inside of update.
const mongoose = require('mongoose');
router.post('/orders_drivers', function (req, res, next) {
console.log(req.body);
Order.update({
_id: mongoose.Types.ObjectId(req.body.id)
},
{
$set: {
driver:req.body.driver, driverReq:false
}
},
{ new: true }, // If you want to return updated order
function (err, updatedOrder) {
if (err) throw err;
console.log('UPDATE new driver', updatedOrder);
})
});
You don't need to convert req.body.id into mongoose ObjectId if it already is.

Capturing response body in Express Middleware

I am trying to write a small API logger as an Express middleware. The logger collects various pieces of information from the req and res, then saves a JSON file to disk that can be read later.
This is my current function to store the logs.
function store(req, res, next) {
init();
const log = {
request_url: req.hostname,
request_body: req.body,
request_method: req.method,
request_headers: req.headers,
api_endpoint: req.baseUrl,
timestamp: moment().format('x')
};
res.on('finish', () => {
log.response_body = res.body;
log.response_status = res.statusCode;
global.enoch_logs.push(log);
fs.writeFile(`./logs/${ moment().format('x') }.json`, JSON.stringify(log), (err) => (err) ? console.log(err) : null);
});
next();
}
The problem is that res.body is always empty. I have tried a few different methods to capture the response body but nothing seems to work.
Where am I going wrong?

res.redirect is not a function in express

I'm currently trying to redirect to an external site with node and express specifically in a get call. However, I can't seem to find a possible solution. Any help would be appreciated. Note that when trying response.redirect I'm getting TypeError: res.redirect is not a function. However, when I view the express documentation it seems to be in there.
app.get('/:urlToForward', (res, req, next)=>{
//Stores the value of param
// var shorterUrl = res.params.urlToForward;
// shortUrl.findOne({'shorterUrl': shorterUrl}, (err,data)=>{
// // if (err) {
// // res.send("This shorterUurl does not exist.");
// // }
// // else {
// // res.redirect(301, data.originalUrl);
// // }
// // response.end();
// });
res.redirect('https://www.google.com');
});
Order matters in the arguments. req must be first, then res, then next.
app.get('/:urlToForward', (req, res, next)=>{ ...
You can do res.redirect('http://app.example.io');
Express docs: http://expressjs.com/api.html#res.redirect
Just use simple:
app is instance of invoked Express application.
app.get('/', function(request,respond) {
respond.redirect('your_url'); //Pass between the brackets your URL.
});
Note you can use ES6 shorthand for shorterUrl, no need to type it out twice.
app.get('/:urlToForward', (req, res, next)=> {
//Stores the value of param
var shorterUrl = res.params.urlToForward;
shortUrl.findOne({shorterUrl}, (err, data)=> {
if (err) {
res.send("This shorterUrl does not exist.");
}
else {
res.redirect(data.originalUrl);
}
response.end();
})
});

Node.js User Authentication

I'm new with nodeJs and i'm actually following a tutorial about it.
In the tutorial, a code was used:
In a verify.js file the following function was written:
exports.verifyOrdinaryUser = function (req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.secretKey, function (err, decoded) {
if (err) {
var err = new Error('You are not authenticated!');
err.status = 401;
return next(err);
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
var err = new Error('No token provided!');
err.status = 403;
return next(err);
}
};
and in another file, the function was called so :
/*****........****/
.post(verify.verifyOrdinaryUser, function(req, res, next){
/******.......*****/
everything is working fine without problem.
1- I don't understand why the function verify.verifyOrdinaryUser is not called so :
verify.verifyOrdinaryUser(req, res, next)
with his parameter (how is it possible that we call a function without his parameter .?
next , i've written a function :
exports.verifyAdmin = function(req, res, next){
if(req.decoded._doc.admin == false){
var err = new Error('You cannot access to this ressource!');
err.status = 401;
return next(err);
}
else {
next();
}
};
in the same file, to verify if a user is a admin or not, i have to call this function after the verifyOrdinaryUser function,
my problem is i don't know how i can make call of this function, with or without the parameters.
Thank you.
1- I don't understand why the function verify.verifyOrdinaryUser is
not called so : verify.verifyOrdinaryUser(req, res, next)
In simplest terms, That's because Express takes care of sending those parameters to the specified middleware instead of you specifying it here
And in function verify.verifyOrdinaryUser, The function is requesting for 3 parameters req, res, next and it receives those three parameters, if it requests for a parameter that doesn't exist, That parameters value will be undefined.
my problem is i don't know how i can make call of this function, with
or without the parameters.
Just call it like
/*****........****/
.post(verify.verifyOrdinaryUser, verify.verifyAdmin, function(req, res, next){
/******.......*****/
And in the functions code you can request for the parameters you need
exports.verifyAdmin = function(req, res){
if(req.decoded._doc.admin == false){
...
Hope this gives you some sense on whats going on, You should google for Node JS Middlewares and simple tutorials based on Node JS and Express.

In express.js, res.render() is not working

I'm making a simple webapp with facebook login.
If the facebook login button on my page is clicked,
FB.api(
'/me',
'GET',
{"fields":"id,name,birthday,gender"},
function(response) {
$.post('fb_login', response, "json");
}
);
is called, and a router handles '/fb_login' request; in the router the server checks the id of json object is already in its DB. If not, res.render('signup', ...) should be called.
However it didn't work. I already checked that res.render() was called, but the page 'signup.jade' didn't show up.
Here is my source code of router.
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '1012'
});
/* GET home page. */
router.post('/', function(req, res, next) {
var userid = req.body.id;
if (userid) {
pool.getConnection(function(err, connection) {
if (err) {
console.error('DB Connection error!!');
return;
}
console.log('DB Connection Success!!');
connection.query('use vasket');
connection.query('select count(*) result from user where userID=?',
[userid], function(err, result, field) {
var isAlreadyUser = result[0].result;
console.log(isAlreadyUser);
if (isAlreadyUser == 1) {
req.session.userid = userid;
res.redirect('/');
res.end();
console.log('DB FB Login Success!!');
connection.release();
}
else {
connection.release();
console.log('FIRST TIME!');
//This method was called, but the page rendered didn't
res.render('signup', {id: req.body.id, name: req.body.name, birthday: req.body.birthday, gender: req.body.gender});
}
});
});
} else {
res.redirect('/');
res.end();
}
How can I fix it?
To help debugging maybe you can modify your code like that :
// ... your code before
else {
connection.release();
console.log('FIRST TIME!');
console.log(req.body);
//This method was called, but the page rendered didn't
res.render(
'signup',
{
id : req.body.id,
name : req.body.name,
birthday: req.body.birthday,
gender : req.body.gender
} ,
function(err, html){
if(err) console.log(err);
console.log(html);
//res.send(html);
// trying same but forcing status
res.status(200).send(html);
}
);
}
});
});
} else {
res.redirect('/');
res.end();
}
This is an older question, but it's still in need of a solid answer. I had the exact same problem, but I think I've figured it out.
If the server's returning the proper response, that's not where your problem lies. jQuery (in the browser) will render the response, but you have to tell it to do so.
Here's what I had that was responding properly but not rendering:
$("#getsome").click(function() {
$.get("/task/create");
});
And here's how I got it to render:
$("#getsome").click(function() {
$.get("/task/create", function( data ) {
document.write(data);
});
});
Note that you may not need to replace the entire DOM like I'm doing.
References:
Replacing the entire
DOM
jQuery.get

Categories