Update MongoDB with mongoose - node.js

I trying to update a field in users collection once a user is logged into the application. But the update query is not working at all.
users.js
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var jwt = require('jsonwebtoken');
router.post('/login', function(req,res,next){
let promise = User.findOne({email:req.body.email}).exec();
promise.then(function(doc){
if(doc) {
if(doc.isValid(req.body.password)){
// generate token
let token = jwt.sign({username:doc.username},'secret', {expiresIn : '3h'});
setOnlineStatus(doc.username);
} else {
return res.status(501).json({message:' Invalid Credentials'});
}
} else {
return res.status(501).json({message:'User email is not registered.'})
}
});
promise.catch(function(err){
return res.status(501).json({message:'Some internal error'});
})
})
function setOnlineStatus(username){
console.log(username); // log the correct username value
User.update(
{'username': username},
{$set: {'status':'Online'}},
);
}
Model - user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt');
var schema = new Schema({
email : {type:String, require:true},
username: {type:String, require:true},
password:{type:String, require:true},
creation_dt:{type:Date, require:true}
});
schema.methods.isValid = function(hashedpassword){
return bcrypt.compareSync(hashedpassword, this.password);
}
module.exports = mongoose.model('User',schema);
So now the problem is once a request is send to /login service, the call to setOnlineStatus() is not updating users collection with a new field status having value 'online'.
NOTE: Using another service /register users are already added to the users collection.
I'm a newbie to express and mongodb. So please help me to solve this issue.
Thank you and answers will be appreciated.

you need to define status in the schema as mongoose will ignore it while updating other wise (read: option: strict)
try adding status: {type: String} to your schema
also the update() function returns a query (read: Model.update()) it doesn't update unless you pass a callback or execute it with .exec()
User.update({'username': username}, {$set: {'status':'Online'}}).exec()

Related

Correct approach to mongoose schema collection property

I need to read a collection identified connected to a mongoose model. Is the correct approach to read the property model.schema.options.collection directly or is there any more suitable approach?
As far as i have understood, you want to use the property of your mongoose schema. i will provide you with a small example to how you can use it effectively.
Your model file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//Schema for User
var UserSchema = new Schema({
name: {
type: String,
},
email: {
type: String
},
password: {
type: String,
},
});
module.exports = mongoose.model('User', UserSchema);
In your function where you want to include this model
var User = require('/path/models/user');
var UserController = {
create: function(req, res){
var user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.password = req.body.password;
//rest of the functionality on these bod params.
}
}
I hope this small example will be able to help.

How to cascade delete using Mongoose remove middleware?

I'm trying to delete all dependencies of a schema when a DELETE request is sent to my API. Deleting goes ok, but the remove middleware, which is supposed to clean the dependencies, seems like is not even getting called.
This is my Customer schema:
var mongoose = require("mongoose"),
Schema = mongoose.Schema,
passportLocalMongoose = require('passport-local-mongoose');
var Order = require('./order');
var Customer = new Schema({
name: String,
telephone: Number,
address: String,
email: String,
seller: String
});
Customer.post('remove', function(next) {
Order.remove({ customer: this._id }).exec();
next();
});
Customer.plugin(passportLocalMongoose);
module.exports = mongoose.model("Customer", Customer);
And this is my customer route:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var isAuthenticated = require('./isAuthenticated');
var Customer = require('../models/customer');
var Order = require('../models/order');
// (...)
router.delete('/:customer_id', function(req, res) {
Customer.remove({ _id: req.params.customer_id }, function(err) {
if (err)
res.json({ SERVER_RESPONSE: 0, SERVER_MESSAGE: "Error deleting", ERR: err });
else res.json({ SERVER_RESPONSE: 1, SERVER_MESSAGE: "Customer deleted" });
});
});
// (...)
I did look this question and Mongoose Docs (Mongoose Middleware) but it's still unclear to me. I don't know what I'm missing or doing wrong.
Thanks in advance!
EDIT
This is my project's repository. Please, feel free to look into.
I finally found the solution to this. Middleware wasn't firing because you must use remove(), save(), etc on model instances, not the model itself.
Example:
Customer.remove({...}); won't work.
Customer.findOne({...}, function(err, customer) {
customer.remove();
});
will work and will do whatever is in Customer.post('remove').
Seems like this is the part you're focusing on:
Customer.post('remove', function(next) {
Order.remove({ customer: this._id }).exec();
next();
});
What you're doing wrong here is that the post hook is not given any flow control, so the next parameter is not actually a function but the document itself.
Change it up to this and you should get what you want:
Customer.post('remove', function(doc) {
Order.remove({ customer: doc._id }).exec();
});
From the docs:
post middleware are executed after the hooked method and all of its
pre middleware have completed. post middleware do not directly receive
flow control, e.g. no next or done callbacks are passed to it. post
hooks are a way to register traditional event listeners for these
methods.

node.js mongodb update error

I have a node.js website. I am using mongoose to connect with my mongodb. Adding new records works fine and find also works fine.
But when I update the record it throws the error below. I have a callback function but dont know whats wrong.
throw new Error("writeConcern requires callback")
^
Error: writeConcern requires callback
Below is my update code.
var newUser = new User();
newUser.update({ 'local.email' : emailID }, { 'local.resetkey': ResetHash }, { multi: false }, function (err, res) {
if (err) return handleError(err);
console.log('The raw response from Mongo was ', raw);
});
This is my schema...
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var safe = { w: "0" };
// define the schema for our user model
local : {
email : String,
password : String,
resetkey : String,
resetexpiry : String,
},
});
module.exports = mongoose.model('User', userSchema);
newUser is a document, but you are calling update as it is defined for the model and therefore getting a wrong argument in place of the callback
Try: User.update(... as in the mongoose API docs: Model.update(conditions, update, options, callback);
You show incomplete code for your schema.

Mongoose save callback doesn't fire

I'm new to mongoose and I'm having a hard time finding the issue within my code. I'm building a REST server using Sails.js and Mongoose. I have a node module (e.g. "sails-mongoose") for exporting mongoose, where I also connect to my database:
var mongoose = require('mongoose');
mongoose.connect('mongodb://#localhost:27017/fooria');
module.exports = mongoose;
And in my model.js:
var adapter = require('sails-mongoose');
var schema = new adapter.Schema({
firstname: {
type: String,
required: true,
trim: true
}
});
module.exports = {
schema: schema,
model: adapter.model('Collection', schema)
}
In my controller's create method I have:
create: function(req, res, next) {
var userData = {firstname: 'Test'};
var users = new Users.model(userData);
users.save(function(err, data){
if (err) return res.json(err, 400);
res.json(data, 201);
});
}
When running create method, the entry is saved to the Mongodb collection but the callback is never reached. Can someone please help me on this track, as I found similar questions but none helped me though. Thanks!
I suppose your are using Express. According Express docs you are calling res.json using incorrect parameters (wrong order).
Correct format:
res.json(code, data)
Example:
res.json(500, { error: 'message' })

mongoose find().all()

Windows 7 x64, node.js, mongoose from npm.
var sys = require('util');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:28960/test_mongoose');
var Schema = mongoose.Schema;
//Model
var UserSchema = new Schema({
username : String,
uid : String,
messaged_on : Date
});
mongoose.model('User', UserSchema);
var User = mongoose.model('User');
// create a new user
var user = new User({
uid : '54321',
username : 'Bob',
messaged_on : Date.now()
});
user.save( function (err) {
if (err)
return;
console.log('Saved');
User.find().all(function(user) {
console.log('beep');
});
});
Connection to mongod accepted, database 'test_mongoose' created.
Console print 'Saved', but 'beep' not.
I am newbie in mongoose, but, what is a prolem? Why do User.find().add() not call function back (user)?
Sorry for my bad english.
Maybe is it normal?
You should be calling User.find(... instead of User.find().all(.... The all method invokes the $all operator which is only used when matching arrays.

Resources