8

I'm populating my DB with some dummy data where I'm trying to add a user. A user object is created but none of the properties are save... whats up?

app.get('/setup', function (req, res) {

    User.findOne({ name: "Nick" }, function (err, user) {

        if (user == undefined) {

            var nick = new User({
                name: "Nick",
            }).save();

            res.json({ "success": true, "msg": "user created" });
        } else {
            res.json({ "success": true, "msg": "user existed" });
        }
    });
});

calling this returns "user created". Here is my method to output all users:

app.get('/users', function(req, res) {

    User.find({}, function(err, user) {
        res.json(user);
    });
});

The output here is

[
  {
    "_id": "565772db5f6f2d1c25e999be",
    "__v": 0
  },
  {
    "_id": "5657734ba859fefc1dca77db",
    "__v": 0
  },
  {
    "_id": "5657738ba859fefc1dca77dc",
    "__v": 0
  },
  {
    "_id": "565774f1cf99a2b81fca1e7f",
    "__v": 0
  },
  {
    "_id": "565775f0cf99a2b81fca1e80",
    "__v": 0
  }
]

Where I've tried to add "Nick" a couple of times noe... any input? :D

My Mongoose model, located in its own Model.js file with other models:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// set up a mongoose model and pass it using module.exports
module.exports = mongoose.model('User', new Schema({ 
    name: String, 
    password: String, 
}));
john-jones
  • 7,490
  • 18
  • 53
  • 86
Jason94
  • 13,320
  • 37
  • 106
  • 184
  • 1
    Change save to `.save(function(err,user){ console.log(err)}) ` to see if there was any error – Molda Nov 26 '15 at 21:29
  • Where does the User object come from? Are you using mongoose? – tmuecksch Nov 26 '15 at 21:40
  • No errors and I'm using mongoose yes – Jason94 Nov 26 '15 at 21:46
  • Then I'd suggest to add the corresponding tag in order to get better answers and not confuse people assuming your script is relying on pure mongo. – tmuecksch Nov 26 '15 at 21:47
  • Thank you for pointing that out, added the tag and added the model I'm using. – Jason94 Nov 27 '15 at 09:30
  • 2
    I tested your exact set up and everything worked. It was able to save a new user with the name field. I would recommend Lisa's set up. – jjbskir Nov 28 '15 at 23:15
  • I also added your snippets in a simple express app and everything was fine. Something might have gone wrong with your mongoose? Clean your dependencies run an npm install and try again. Your code doesn't look great, but nevertheless it should work. – x_maras Dec 02 '15 at 23:43

5 Answers5

5

Given you have a name in you user Schema, you also need to wait until your save() query is finished and then send a response:

app.get('/setup', function (req, res) {
    User.findOne({ name: "Nick" }, function (err, user) {
        if (err) {
          return res.json({ "success": false, "error": err });
        }

        if (user) {
          return res.json({ "success": true, "msg": "user existed" });
        }

        var nick = new User({ name: "Nick" });
        nick.save(function(err, userObj) {
           if (err) {
             return res.json({ "success": false, "error": err });
           }

           res.json({ "success": true, "msg": "user created" });
        });
    });
});
Lisa Gagarina
  • 693
  • 5
  • 7
  • Why do I have to wait? Several seconds is passing by between I'm sending /setup and /users – Jason94 Nov 26 '15 at 21:49
  • 2
    Because save() method is asynchronous and before sending success response you need to make sure there are no errors and document was inserted successfully. – Lisa Gagarina Nov 26 '15 at 22:03
4

please try with this code :

app.get('/setup', function (req, res) {

    User.findOne({ name: "Nick" }, function (err, user) {

        if (!err && user) {
                res.json({ "success": true, "msg": "user existed" });

        } 
        else {

            var nick = new User({name: "Nick" });
            nick.save(function(err){
               if(!err)
                   res.json({ "success": true, "msg": "user created" });
            })

        }
    });
});
yergo
  • 4,761
  • 2
  • 19
  • 41
Md Nazmul Hossain
  • 2,768
  • 5
  • 26
  • 49
3

The save() function you have called is incorrect, and follows the pattern of other languages rather than Node.js.

The way Node.js works is totally different from other languages like Java, PHP, Ruby, ASP.net and etc Javascript is entirely Asynchronous in nature, and Node.js has improved over it as Event-driven and non-blocking I/O. So the code execution doesn't move on unless it has received a response from the function it lies within.

Therefore, after the save() method is executed, it responses back with a callback function sending a completion response to node.js so it can trigger other executions. The correct code will be

var user = new User({name: 'Nick'});
user.save(function(err, savedUser) {
    if(err) return res.send(err);
    return res.json({'message': 'User created!', user: savedUser});
});

So as you can see, that as soon as the save() method completes, it responds back the response i.e. err and savedUser in a callback rather than returning them, and every single of the code after the save method will be written inside that callback.

If we take your code for a minute and analyze what the problem is,

var nick = new User({
    name: "Nick",
}).save();

res.json({ "success": true, "msg": "user created" });

when the save() method is called, node.js sends the data along with insert trigger to mongodb, and moves on with the rest of the code execution. And that code is printing "success" even the data is not being saved yet. Therefore almost every method in Node.js has a callback as it's last parameter which sends an indication of completion.

Rahil051
  • 143
  • 2
  • 7
2

You need to define name key in your User schema for it be saved.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var userSchema = new Schema({
  name: String
});

var User = mongoose.model('User', userSchema);
Kunal Kapadia
  • 3,223
  • 2
  • 28
  • 36
  • Yes, forgot to add that but I've added the name key to the schema. Can I have multiple scemas in the same file? Cuz right now I've got all my "models" in a Models.js file. This include User for one, and also others. – Jason94 Nov 26 '15 at 21:47
  • Yes you can have all your 'models' in the same file but that's not recommended. Also mark answer as accepted if it helped you solving the problem. – Kunal Kapadia Nov 26 '15 at 21:53
  • It did not solve my problem, what I ment was I forgot to add the code. Otherwise "User" would not have worked at all. – Jason94 Nov 27 '15 at 09:26
2

Here is your code and it works. I've only changed the module.exports with var User because of to collect the code in a single page.

So, may be there is another problem?

Good luck...

var express = require('express')
var mongoose = require('mongoose')
var mongoDBUrl = "mongodb://1.0.0.1:27027/tests"

var app = express()

var Schema = mongoose.Schema;
var User = mongoose.model('User', new Schema({ 
    name: String, 
    password: String, 
}));

/* Mongoose Database connection */
mongoose.connect(mongoDBUrl)
var db = mongoose.connection
db.on('error', console.error.bind(console, 'Mongo connection error:'))
db.once('open', function (callback) {
  console.log("MongoDB connection has established")
})

app.get('/setup', function (req, res) {
    User.findOne({ name: "Nick" }, function (err, user) {

        if (user == undefined) {

            var nick = new User({
                name: "Nick",
            }).save();

            res.json({ "success": true, "msg": "user created" });
        } else {
            res.json({ "success": true, "msg": "user existed" });
        }
    });
});

app.get('/users', function(req, res) {
console.log("/user works")

    User.find({}, function(err, user) {
        res.json(user);
    });
});


app.listen(1337, function() {
    console.log('node-app is listening HTTP port 1337')
})

Postman results;

enter image description here

efkan
  • 12,991
  • 6
  • 73
  • 106