0

I am trying to display a list of subject names associated with a training event, however the object id is the only property that is populated after the query has executed. I have tried the solution in this QUESTION which seems to be similar to what I am trying to achieve, but it is not working. My load method is at the very bottom of this code snippet.

Any help is appreciated, thanks.

var UserSchema = new Schema({
    firstName: {
        type: String,
        trim: true,
        default: '',
        validate: [validateLocalStrategyProperty, 'Please fill in your first name']
    },
    lastName: {
        type: String,
        trim: true,
        default: '',
        validate: [validateLocalStrategyProperty, 'Please fill in your last name']
    },
    displayName: {
        type: String,
        trim: true
    }
});


var SubjectSchema = new Schema({
    name: {
        type: String,
        default: '',
        required: 'Please fill subject name',
        trim: true
    },
    description: {
        type: String,
        default: '',
        required: 'Please fill subject description',
        trim: true
    }
});

var TrainingSubjectSchema = new Schema({
    subject: {
        type: Schema.ObjectId,
        ref: 'Subject'
    },
    attendanceRate:[{
        type: Number
    }]
});


var TrainingEventSchema = new Schema({
    name: {
        type: String,
        default: '',
        required: 'Please fill training event name',
        trim: true
    },
    created: {
        type: Date,
        default: Date.now
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    attendees:[{
        type: Schema.ObjectId,
        ref: 'User'
    }],
    subjects:[TrainingSubjectSchema]
});


// retrieve method
Training.findById(id).populate('user', 'displayName').populate('subjects.subject','name').exec(function(err, trainingevent)
Community
  • 1
  • 1
noobie
  • 2,427
  • 5
  • 41
  • 66

1 Answers1

1

Not sure why it is not working in your side but I have tried in my code and it is working as expected.

Here it is how I am creating the Schemas:

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

    mongoose.connect('mongodb://localhost:27017/mongoose_benn');

  var UserSchema = new Schema({
      firstName: {type: String, trim: true, default: ''},
      lastName: {type: String, trim: true, default: ''},
      displayName: {type: String, trim: true}
    });

    var SubjectSchema = new Schema({
      name: {
        type: String,
        default: '',
        required: 'Please fill the subject name.',
        trim: true
      },
      description: {
        type: String,
        default: '',
        required: 'Please fill subject description',
        trim: true
      }
    });

    var TrainingSubjectSchema = new Schema({
      subject: {type: Schema.ObjectId, ref: 'Subject'},
      attendanceRate: [{type: Number}]
    });

    var TrainingEventSchema = new Schema({
      name: {
        type: String,
        default: '',
        required: 'Please fill the training event name.',
        trim: true
      },
      created: {type: Date, default: Date.now},
      user: {type: Schema.ObjectId, ref: 'User'},
      attendes: [{
        type: Schema.ObjectId,
        ref: 'User'
      }],
      subjects: [TrainingSubjectSchema]
    });

    module.exports = {
      User: mongoose.model('User', UserSchema),
      Subject: mongoose.model('Subject', SubjectSchema),
      TrainingSubject: mongoose.model('TrainingSubject', TrainingSubjectSchema),
      TrainingEvent: mongoose.model('TrainingEvent', TrainingEventSchema)
    };

And here I am processing data with the models:

    var async = require('async');
    var models = require('./models.js');
    var User = models.User;
    var Subject = models.Subject;
    var TrainingSubject = models.TrainingSubject;
    var TrainingEvent = models.TrainingEvent;

    async.waterfall(
      [
        clearDB.bind(null, {collections: [User, Subject, TrainingSubject, TrainingEvent], async: async}),
        createUsers.bind(null, {User: User, async: async}),
        createSubjects.bind(null, {async: async, Subject: Subject}),
        createTrainingEvents.bind(null, {async: async, TrainingEvent: TrainingEvent}),
        showTrainingEvents.bind(null, {TrainingEvent: TrainingEvent})
      ]
    );

    function createTrainingEvents(data, db, next) {
      var firstSubject = db.subjects[0];
      var secondSubject = db.subjects[1];

      var trainingSubjects = [
        {
          subject: firstSubject._id,
          attendanceRate: [5, 5]
        },
        {
          subject: secondSubject._id,
          attendanceRate: [4, 4, 5]
        }
      ];

      var trainingEvents = [
        {
          name: 'October Fest',
          user: db.users[0]._id,
          subjects: [trainingSubjects[0]],
          attendes: [db.users[0]._id, db.users[1]._id]
        },
        {
          name: 'August Fest',
          user: db.users[1]._id,
          subjects: [trainingSubjects[1]],
          attendes: [db.users[0]._id, db.users[1]._id]
        }
      ];

      data.async.map(
        trainingEvents,
        function(trainingEvent, done) {
          data.TrainingEvent.create(trainingEvent, done);
        },
        function(err, result) {
          next(err);
        }
      );
    }

    function clearDB(data, next) {
      async.map(
        data.collections,
        function(collection, done) {
          collection.remove({}, done);
        },
        function(err) {
          next(err);
        }
      );
    }

    function createUsers(data, next) {
      var users = [
        {firstName: 'Wilson', lastName: 'Balderrama', displayName: 'Wily'},
        {firstName: 'Santiago', lastName: 'Balderrama', displayName: 'Santi'},
        {firstName: 'Keila', lastName: 'Balderrama', displayName: 'Kei'}
      ];

      data.async.map(
        users,
        function(user, done) {
          data.User.create(user, done);
        },
        function(err, results) {
          next(err, {users: results});
        }
      );
    }

    function showUsers(data, next) {
      data.User.find({}, function(err, users) {
        next();
      });
    }

    function createSubjects(data, db, next) {
      var subjects = [
        {
          name: 'JavaScript for Beginners',
          description: 'JS fundamentals'
        },
        {
          name: 'Node.JS for Beginners',
          description: 'Node.JS streams'
        }
      ];

      data.async.map(
        subjects,
        function(subject, done) {
          data.Subject.create(subject, done);
        },
        function(err, result) {
          db.subjects = result;
          next(err, db);
        }
      );
    }

    function createTrainingSubjects(data, db, next) {
      var firstSubject = db.subjects[0];
      var secondSubject = db.subjects[1];

      var trainingSubjects = [
        {
          subject: firstSubject._id,
          attendanceRate: [5, 5]
        },
        {
          subject: secondSubject._id,
          attendanceRate: [4, 4, 5]
        }
      ];


      data.async.map(
        trainingSubjects,
        function(trainingSubject, done) {
          data.TrainingSubject.create(trainingSubject, done);
        },
        function(err, result) {
          db.trainingSubjects = result;
          next(err, db);
        }
      );
    }

    function showTrainingSubjects(data, next) {
      data.TrainingSubject
        .find({})
        .populate('subject')
        .exec(function(err, data) {
          next();
        });
    }

    function showSubjects(data, next) {
      data.Subject.find({}, function(err, data) {
        next();
      });
    }

    function showTrainingEvents(data, next) {
      data.TrainingEvent
        .find({name: 'August Fest'})
        .populate('user', 'displayName')
        .populate('subjects.subject', 'name')
        .exec(function(err, data) {
          console.log(JSON.stringify(data));
          next();
        });
    }

And the output is;

    [
       {
          "_id":"55981d58cfd48c905c3a5fde",
          "user":{
             "_id":"55981d58cfd48c905c3a5fd8",
             "displayName":"Santi"
          },
          "__v":0,
          "subjects":[
             {
                "subject":{
                   "_id":"55981d58cfd48c905c3a5fdb",
                   "name":"Node.JS for Beginners"
                },
                "_id":"55981d58cfd48c905c3a5fdf",
                "attendanceRate":[
                   4,
                   4,
                   5
                ]
             }
          ],
          "attendes":[
             "55981d58cfd48c905c3a5fd7",
             "55981d58cfd48c905c3a5fd8"
          ],
          "created":"2015-0704T17:52:24.181Z",
          "name":"August Fest"
       }
    ]
Wilson
  • 9,006
  • 3
  • 42
  • 46