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)
2
  • Do you have a model initialized for subject? mongoose.model('Subject', SubjectSchema); Otherwise i believe ref: 'Subject' Wont work Commented Jul 4, 2015 at 12:06
  • Yes, I do. I just let it out from my code snippet. Commented Jul 4, 2015 at 23:10

1 Answer 1

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"
       }
    ]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, going through your code helped me pick up two bugs in my client side code which caused the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.