Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.save() is not a Function Mongoose

I keep getting an issue that newUser.save() is not a function. This is a mongoose function that I have used before. I required mongoose correctly and am unsure of why this error is occurring. Any help is welcomed.

The error I am getting is TypeError: newUser.save is not a function

My user.js inside the Models Folder

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

var UserSchema = new Schema({
  name: String,
  email: String,
  password: String,
  info: String
});

var User = module.exports = mongoose.model('User', UserSchema);

module.exports.createUser = function(newUser, callback){
    bcrypt.genSalt(10, function(err, salt) {
        bcrypt.hash(newUser.password, salt, function(err, hash) {
            newUser.password = hash;
            newUser.save(callback);
        });
    });
}

module.exports.getUserByUsername = function(username, callback){
    User.findOne({username : username}, callback);
}

module.exports.getUserById = function(id, callback){
    User.findById(id, callback);
}

module.exports.checkPassword = function(candidatePass, hash, callback){
  bcrypt.compare(candidatePass, hash, function(err, res) {
    if(err) throw err;
    callback(null, res);
  });
}

My users.js inside the Routes Folder

//Mongoose Setup
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect("MY_DB");
var path = require('path');
var appDir = path.dirname(require.main.filename);
var bodyParser = require('body-parser')
var User = require('../models/user.js');

//Express Setup
var express = require('express');
var router = express.Router();
var app = express();
var expressValidator = require("express-validator");

app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator());
app.use(bodyParser.json());

//Routes
router.get('/register', function(req, res){
  res.sendFile(appDir + "/views/register.html");
})

router.post('/register', function(req, res) {
  req.check('name', 'Name must be Filled in').notEmpty();
  req.check('email', 'Email must be Filled in').notEmpty();
  req.check('email', "Invalid Email").isEmail();
  req.check('password', 'Password Field must be Filled in').notEmpty();
  req.check('password', 'Passwords do not Match').equals(req.body.password2)
  var errors = req.validationErrors();
  if(errors) res.send(errors)
  else{ User.createUser({
    name: req.body.name,
    email: req.body.email,
    password: req.body.password,
    info: req.body.user_bio
  }, function(){
    console.log('User Created');
  })
}
})

//Exports
module.exports = router;
like image 823
That Guy Avatar asked May 30 '16 19:05

That Guy


People also ask

What is Save () in Mongoose?

save() is a method on a Mongoose document. The save() method is asynchronous, so it returns a promise that you can await on.

Is Mongoose save a Promise?

While save() returns a promise, functions like Mongoose's find() return a Mongoose Query . Mongoose queries are thenables. In other words, queries have a then() function that behaves similarly to the Promise then() function. So you can use queries with promise chaining and async/await.

Does Mongoose save overwrite?

Mongoose save with an existing document will not override the same object reference. Bookmark this question.


2 Answers

You have got some things wrong here.

Something like this (User refers to your schema):

var user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.password = req.body.password;
user.info = req.body.user_bio;
user.save().then(function(err, result) {
    console.log('User Created');
});

should work better. Instead of passing a new object (which obviously doesn't contain the save method), you are now creating a new object from the schema, setting the parameters, and then save it.

You then also have to change to this:

User.pre('save', function(next) {
    bcrypt.genSalt(10, function(err, salt) {
        bcrypt.hash(this.password, salt, function(err, hash) {
            this.password = hash;
            next();
        });
    });
}

This is a hook, which is called every time before the user gets saved.

like image 155
Peter Keuter Avatar answered Sep 29 '22 08:09

Peter Keuter


createUser() is a regular function that you're passing a regular object (as the newUser argument) to:

User.createUser({
  name : req.body.name,
  ...
}, ...);

Regular objects don't have a .save method.

What you probably want is to create a static method as part of your model. That would allow you to call User.createUser like you are doing now (notice how static methods are created on the schema, not the model. Also, you have to define static methods before creating a model from the schema)

like image 38
robertklep Avatar answered Sep 29 '22 08:09

robertklep