sasuri
sasuri

Reputation: 992

Why save() in mongoose is not a function?

I'm developing an app using Node.js, Mongoose, MongoDb, express.

I have 2 schemas one for student and one for snippets. I'm using the population model population model. I can create a user, and create a snippet and link it to the user. But I can't link and save the snippets in the user collection.

How to link and save the user so that it can have a reference to his snippets?

user and snippet schema

var userSchema = Schema({
       name: { type: String, required: true, unique: true },
     password: { type: String, required: true },
    snippet: [{ type: Schema.Types.ObjectId, ref: 'Snippet' }]
    })

   var snippetSchema = Schema({
   user: {type: Schema.Types.ObjectId, ref: 'User'},
    title: String,
   body: String,
    createdAt: {
    type: Date,
   require: true,
    default: Date.now
     }
    })

This is how I save the snippets I add it inside a user .save() function so that it saves the snippet ref but it gives me user.save() is not a function error.

   var name = request.session.name.name
   User.find({ name: name }).then(function (user) {
    if (user) {
      console.log('====================')
      console.log(user)
      user.save().then(function () {    // problem is here? 
        var newSnippet = new Snippet({
          user: user._id,
          title: title,
          body: snippet
        })

        newSnippet.save().then(function () {
          // Successful
          console.log('success')

          response.redirect('/')
        })
      })
    }
  }).catch(function (error) {
    console.log(error.message)
    response.redirect('/')
  })

But, I actually get the object printed after searching for it!

[ { _id: 5a2e60cf290a976333b19114,
name: 's',
password: '$2a$10$vD3EaQly4Sj5W3d42GcWeODuFhmHCSjfAJ1YTRMiYAcDBuMnPLfp6',
__v: 0,
snippets: [] } ]

Upvotes: 0

Views: 76

Answers (1)

Cohars
Cohars

Reputation: 4022

You need to use User.findOne to get a valid user object, here you get an array. Also, don't forget to always return something in you promises (or throw an error).

Here is a quick rewrite of your function. With a few improvements such as arrow functions, const and a flat promise chain (never using any .then inside another .then) and avoiding code repetition

const name = request.session.name.name
User.findOne({ name })
  .then(user => {
    if (user) return user.save()

    // What to do if not found? Throw an error?
    throw new Error('User not found')
  })
  .then(() => {
    const newSnippet = new Snippet({
      user: user._id,
      title: title,
      body: snippet,
    })

    return newSnippet.save()
  })
  .catch((error) => console.log(error.message))
  .then(() => response.redirect('/'))

Upvotes: 2

Related Questions