JVG
JVG

Reputation: 21170

Mongoose Schema: Forcing an array of objects to be created

My Mongoose schema looks like this:

var userSchema = mongoose.Schema({

  fbid       : String,
  googleid   : String,
  birthday   : String,
  email      : String,
  first_name : String,
  last_name  : String,
  gender     : String,
  age        : Number,
  location   : String,
  paid       : { type: Boolean, default: 0 },
  lessons: [
    { 
      name    : { type: String,  default: 'foobar1'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar2'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar3'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar4'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar5'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar6'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar7'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    },
    { 
      name    : { type: String,  default: 'foobar8'},
      sent    : { type: Boolean, default: 0 },
      read    : { type: Boolean, default: 0 },
      activity: { type: Boolean, default: 0 }
    } 
  ]

});

When doing new User(), everything is created properly except for the lessons array, which returns as an empty array rather than creating the nested objects with their default values.

It is possible to make these objects when doing new User(), but I want this to occur in the model itself as all users will have the same lessons and same initial values.

How can I make this happen?

Upvotes: 0

Views: 1396

Answers (3)

hankchiutw
hankchiutw

Reputation: 1662

Set default value in your schema declaration:

var defaultLessons = [
    { 
      name    : 'foobar1',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar2',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar3',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar4',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar5',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar6',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar7',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    ,
    { 
      name    : 'foobar8',
      sent    : 0 ,
      read    : 0 ,
      activity: 0 
    } 
  ];

var userSchema = new mongoose.Schema({
  ...
  lessons: { type: [], default: defaultLessons}
});

Another more structure way is to use sub docs:

var lessonSchema = new mongoose.Schema({                                                                         
  name    : { type: String,  default: 'foobar'},
  sent    : { type: Boolean, default: 0 },
  read    : { type: Boolean, default: 0 },
  activity: { type: Boolean, default: 0 }
});

var defaultLessons = [ 
    {  
      name    : 'foobar1', 
    }, 
    {  
      name    : 'foobar2', 
    }, 
    {  
      name    : 'foobar3', 
    }, 
    {  
      name    : 'foobar4', 
    }, 
    {  
      name    : 'foobar5', 
    }, 
    {  
      name    : 'foobar6', 
    }, 
    {  
      name    : 'foobar7', 
    }, 
    {  
      name    : 'foobar8', 
    }  
  ];

var userSchema = new mongoose.Schema({
  ...
  lessons: { type: [lessonSchema], default: defaultLessons}
});

However, above does not work in mongoose 4+, I've tried mongoose 3.8 ok. See this discussion.

Upvotes: 0

Sandeep Sharma
Sandeep Sharma

Reputation: 1885

Following link would be helpful for setting default values for nested Array in mongoose Schema.

set default values to mongoose arrays in node js

You could do like this:

var lessonSchema = Schema({
    name: { type: String },
    sent: { type: Boolean },
    read: { type: Boolean },
    activity: { type: Boolean }
});

var userSchema = Schema({
    fbid: { type: String },
    googleid: { type: String },
    birthday: { type: String },
    email: { type: String },
    first_name: { type: String },
    last_name: { type: String },
    gender: { type: String },
    age: { type: Number },
    location: { type: String },
    paid: { type: Boolean, default: 0 },
    lessons: [lessonSchema]
});

userSchema.pre("save", function (next) {
    if (!this.lessons || this.lessons.length == 0) {
        this.lessons = [];
        this.lessons.push({
            "name": "football 1",
            "sent": true,
            "read": true,
            "activity": true
        })

         this.lessons.push({
            "name": "football 2",
            "sent": true,
            "read": true,
            "activity": true
        })

         this.lessons.push({
            "name": "football 3",
            "sent": true,
            "read": true,
            "activity": true
        })

         this.lessons.push({
            "name": "football 3",
            "sent": true,
            "read": true,
            "activity": true
        })
    }
    next();
});

Upvotes: 2

gabesoft
gabesoft

Reputation: 1228

You could add a pre save hook in your schema

schema.pre('save', function(next) {
  if (this.isNew) {
    this.set('lessons', [ ... ]);
  }
  next();
});

More info here http://mongoosejs.com/docs/middleware.html

Upvotes: 1

Related Questions