Node.js / Express.js Removing user from request, removes it from database - node.js

Here is the code:
exports.delete = function (req, res, next) {
console.log(req.user);
req.user.remove(function (err) {
if(err) {
return next(err);
} else {
res.json(req.user);
}
})
};
Of course this function is callback of delete method, what I don't understand is that, why removing req.user also deletes the specific user from MongoDB, as it is just a request.
Edit:
I have another callback(GET) which is executed on the same route:
exports.userByID = function (req, res, next, id) {
User.findOne({
_id: id
}, function (err, user) {
if (err) {
return next(err);
} else {
req.user = user;
next();
}
});
};
User is MongoDB model.

Where you do your req.user = user you're setting the value of req.user to the instance of your mongodb model.
So, calling req.user.remove is in fact calling your mongodb model remove function.
Change your delete function to:
exports.delete = function (req, res, next) {
console.log(req.user);
delete req.user
//etc...
};
delete req.user will remove the user object from your request object

Related

How to pass Data Between multiple routes in express?

app.post("/login", passport.authenticate("local",), function (req, res) {
const user = new Model({
username: req.body.username,
password: req.body.password,
});
req.login(user, function (err) {
if (err) {
console.log("wrong password");
} else {
passport.authenticate("local")(req, res, function () {
res.redirect("/admin");
});
}
});
});
app.post("/admin", function (req, res) {
Model.findOne({username: "siddharth"}).exec(function(err, foundList){
if(foundList)
{
const list = new linkModel({
linkTitle: req.body.linkTitle,
linkUrl: req.body.linkUrl,
});
foundList.links.push(list);
foundList.save();
res.redirect("/admin");
}
else
{res.send("redirect to home page and then login");
res.redirect("/login");
}
});
});
How can i pass the username when authenticated from login routeto other route(admin) where mongoose query is defined findone?
As i have defined it explicitly.
Or i simple terms how can i pass the data among routes ?
You can't. Instead use a middleware to do the checks you want and pass on the result to another middleware or return the response in case of error.

Thinkster node.js tutorial

Question about the profile route, why do we have 2 methods that presumably do the same thing: User.findOne and User.findById? Also what is the order of execution for the router.param and router.get?
router.param('username', function(req, res, next, username){
User.findOne({username: username}).then(function(user){
if(!user) { return res.sendStatus(404); }
req.profile = user;
return next();
}).catch(next);
});
router.get('/:username', auth.optional, function(req, res, next){
if(req.payload){
User.findById(req.payload.id).then(function(user){
if(!user) { return res.json({profile: req.profile.toProfileJSONFor(false)}); }
return res.json({profile: req.profile.toProfileJSONFor(user)});
});
} else {
return res.json({profile: req.profile.toProfileJSONFor(false)});
}
});
Very simply put:
FindOne queries the database to match against custom identifiers whereas findById queries the database to match a unique identifier.
Also in Express, the routes you define are matched sequentially in the order that they are defined.

express js URL cleanup

I create a rout that get user full details from the DATABASE(mongoDB).
Router
router.get('/user/:userid/:name', getUrl, function(req, res, next) {
User.findOne({_id: req.params.userid})
.exec(function(err, user) {
if (err) { return next(err); }
if (!user) { return next(404); }
res.render('........');
});
});
for instance i can access this router with this URL:
http://127.0.0.1/user/6465667/username
but what i realy want is this
http://127.0.0.1/user/username
Is there a way of hiding the user ID in the URL
Simply remove :userid from your route and use the name to lookup your database. Ensure your username is unique otherwise you might receive the wrong user details.
router.get('/user/:name', getUrl, function(req, res, next) {
User.findOne({name: req.params.name})
.exec(function(err, user) {
if (err) { return next(err); }
if (!user) { return next(404); }
res.render('........');
});
});

Returning an Object from middleware function in Node.JS

I am new to Node.JS coming from a Java Background I am using express to build this Rest API . What I am trying to do is build the concept of a manager. I am looking for a elegant way of returning a user object in the following:
users route: user.js
router.get('/find/:email', function(req, res, next){
userWare.findUserByEmail(req, res, next)
});
middleware/manager: usermiddleware.js
module.exports = {
findUserByEmail: function(req, res, next) {
models.core_user.find({
where:{
email: req.params.email
}
}).then(function(user){
res.json(user)
}, function(err){
res.status(404).json(err);
});
},
}
So In this above function I would like to return the user object to the route instead of the json. so that I can create the json from the object in the route. The whole point of this manager class will be to fectch and return objects.
What you need to do is call the callback function with the data you need or return the promise.
Callback
user.js
router.get('/find/:email', function (req, res, next) {
userWare.findUserByEmail(req.params.email, function (err, data) {
// error as first parameter or null if no error occurred
if (err) {
return res.status(404).json(err);
}
res.json(user);
});
});
usermiddleware.js
module.exports = {
findUserByEmail: function (email, next) {
models.core_user.find({
where: {
email: email
}
}).then(
function (user) {
// async call of callback with user object
next(null, user);
},
function (err) {
// async call of callback with error
next(err);
}
);
}
};
Promise
You could also just return the promise returned by your model, then it would look like this:
user.js
router.get('/find/:email', function (req, res, next) {
userWare.findUserByEmail(req.params.email).then(
function (user) {
res.json(user);
},
function (err) {
res.status(404).json(err)
}
);
});
usermiddleware.js
module.exports = {
findUserByEmail: function (email) {
// return the promise to the caller
return models.core_user.find({
where: {
email: email
}
});
}
};

Trying to update res.locals after database update

When updating a user (via database update) in my Node.JS Express app, I update a user session which then updates a res.locals.session
However, when I try to access the res.locals.session within the Jade template, the values are displayed as they were prior to the database update.
Please can you help me to find out why the res.locals.session is not updating in the template?
Here is my code (cut down for brevity):
index.js
// Store session to locals so I can use it in Jade
app.use(function (req, res, next) {
res.locals.session = req.session;
next();
});
routes/user.js
var User = require('../models/Users');
function displaySettings(req, res) {
res.render('settings');
}
function saveSettings(User, req, res) {
// Updating user
User.update(
{ Member_id: req.session.user.Member_id }
, { settings: req.body }
, { upsert: false, multi: false }
, function (err) {
//if(err) return next(err);
//res.json({ message : 'Success!'});
console.log("saved");
});
// Retrieving user again, so that I can resave the updated user's details
// in the res.locals.session
var user = User.findById(req.session.user._id, function (err, user) {
console.log("found");
console.log(user);
req.session.user = user;
console.log(req.session.user);
res.locals.session = req.session;
console.log(res.locals.session);
});
// Finally display the view
displaySettings(req, res);
}
views/settings.jade
extends layout
block content
include includes/navigation
div.container.main
h1.text-center User Settings
div.row
div.col-md-6.col-md-offset-3
form#form-login.form-horizontal(action='/settings',method='post')
div#container(data-role='fieldcontain')
fieldset(data-role='controlgroup')
div.form-group
label.col-sm-4.control-label(for='username') Paypal Email
div.col-sm-8
// The session.user.settings.paypalEmail is showing
// the old value even after the user has re-saved
// their settings. I'm expecting the new, updated
// value to be displayed instead
input.form-control(id='username',type='text',value='#{session.user.settings.paypalEmail}',name='paypalEmail')
Try using res.redirect('settings') instead of calling displaySettings(req, res). I think this will allow res.locals to update.
what about rewriting the saveSettings as follows.
function saveSettings(User, req, res) {
// Updating user
User.update(
{ Member_id: req.session.user.Member_id }
, { settings: req.body }
, { upsert: false, multi: false }
, function (err) {
//if(err) return next(err);
//res.json({ message : 'Success!'});
console.log("saved");
// Retrieving user again, so that I can resave the updated user's details
// in the res.locals.session
var user = User.findById(req.session.user._id, function (err, user) {
console.log("found");
console.log(user);
req.session.user = user;
console.log(req.session.user);
res.locals.session = req.session;
console.log(res.locals.session);
// Finally display the view
displaySettings(req, res);
});
});
}

Resources