3
votes

I have a user profile, I have a field of 'earning' and it look like this in the schema

earning: { type: Schema.Types.ObjectId, ref: 'Earning' }

This how do I make a default value for earning field when a new user is created? I can't do this

earning: {
    type: Schema.Types.ObjectId,
    ref: 'Earning',
    default: 0
  }

I got error of Cast to ObjectId failed for value "0" at path "earning"

3

3 Answers

4
votes

What you are doing wrong here is trying to cast a number on an ID field. Since it's a reference of another object Id field, you can not set 0 to it. What you need to do is to set null when a user is created in db and initialize it with a null value of earning. Like:

earning: {
  type: Schema.Types.ObjectId,
  ref: 'Earning',
  default: null
}
1
votes

As I understand earning is indication of how much user earn so it should be of type Number not ObjectId

so try to change your Schema to be

earning: {
type: Number,
ref: 'Earning',
default: 0

}

so you can use 0

Note: if you should use ObjectId for some reason so the answer of 'Haroon Khan' is the correct answer.

1
votes

When instantiating a document based on a Schema which has a key of type 'ObjectId' and a ref to another collection, the only way that I've found to set a 'default' value is through the use of Mongoose middleware at the schema level as described here. For example, setting a comment's author to a default 'guest' document from a User collection when the author is not logged in might look like this:

// user document in MongoDB
{  
  _id: ObjectId('9182470ab9va89'),
  name: 'guest'
}

// CommentSchema
const mongoose = require('mongoose')

const CommentSchema = mongoose.Schema({
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
  },
  body: String
})

CommentSchema.pre('save', function (next) {
  this.author == null ? this.author = '9182470ab9va89' : null
  next()
})

module.exports = mongoose.model('Comment', CommentSchema)

This example uses the 'save' pre hook with the ObjectId hardcoded in the schema for demonstration purposes, but you can replace the hardcoding of the ObjectId with a call to your backend or however else you'd like to get that value in there.