9

I've spent all morning googling this, and trying various fixes but I cannot figure it out.

I keep getting the error "TypeError: req.user.findOneAndUpdate is not a function" when I try to run this:

req.user.findOneAndUpdate({_id: req.user._id}, { $addToSet: { flashcards : { $each: cards }}}, {upsert : true}, function(err, doc) {
        if(err) return console.log(err);
        res.send(doc);
    });

I've tried explicitly turning req.user into a User model (eg var NewUser = new User(req.body), tried simplifying the query etc but nothing seems to work.

Edit: With model declaration

const User = require('../models/user');

var NewUser = new User(req.user);

    NewUser.findOneAndUpdate({_id: req.user._id}, { $addToSet: { flashcards : { $each: cards }}}, {upsert : true}, function(err, doc) {
        if(err) { return console.log(err); }
        else { return res.send(doc);}
    });

User model schema

const mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    FlashcardSchema = require('./flashcardSchema'),
    bcrypt = require('bcrypt-nodejs');

var UserSchema = new Schema({
    username: {
        type: String,
        required: false
      },
      email: {
        type: String,
        required: true,
        unique: true
      },
      password: {
        type: String
      },
      created_on: {
        type: Date,
        default: Date.now
      },
        points: Number,
        flashcards: [FlashcardSchema],
        courses: [{type: Schema.Types.ObjectId, ref: 'Course'}]
});

UserSchema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

UserSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.password);
};

module.exports = UserSchema;

And the model

const mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    UserSchema = require('../schemas/userSchema');

module.exports = mongoose.model('User', UserSchema);
Coreylh
  • 131
  • 1
  • 1
  • 8

2 Answers2

28

The solution is to run functions on a model, not on a instance of it. So instead of:

var NewUser = new User(req.user);
NewUser.findOneAndUpdate...

Do:

User.findOneAndUpdate...
vicbyte
  • 3,690
  • 1
  • 11
  • 20
  • Whats the difference between running on an instance and running on model ? could you please share some more details :) – Usman Iqbal Feb 25 '21 at 07:28
  • 1
    @UsmanI The `findOneAndUpdate` is just a [static member of the Model class](https://github.com/Automattic/mongoose/blob/master/lib/model.js#L2450). So you need to call it on class itself and not on object. – vicbyte Mar 27 '21 at 17:49
0

You are returning after checking err so

req.user.findOneAndUpdate({_id: req.user._id}, { $addToSet: { flashcards : { $each: cards }}}, {upsert : true}, function(err, doc) {
        if(err) {return console.log(err);}
        else {return res.send(doc);}
    });
user8803663
  • 80
  • 1
  • 11