0

I am developing an online course application. I have created a collection for course enrollment where I am storing the course name and the users enrolled in that course. Mongoose schema looks like this. its name is courseEnrollment.js.

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

var courseEnrollment = new Schema({


courseEnrolled: [{courseName : String},
                 {username : [{user : String}]}
                ]

}, {collection : 'courseEnrollment'});

module.exports = mongoose.model('courseEnrollment', courseEnrollment);

When a user clicks on enroll, then the GET request will go to 'localhost:3000/learn/:courseName/enroll' . In that route handler I am storing the user course enrollment information in two different collection. 1) In courseEnrollment collection, which I showed above. 2) In the user account information, where username, password, etc is stored, there I am also storing course enrolled by user.

Now the problem I am facing right now is, it only updates the User collection, and not the courseEnrollment collection for some reason.It gives following error.

events.js:141
  throw er; // Unhandled 'error' event
  ^

TypeError: Cannot read property 'push' of undefined
at /home/mobileedx/WebstormProjects/passportAuthentication/routes/index.js:387:47
at Query.<anonymous> (/home/mobileedx/WebstormProjects/passportAuthentication/node_modules/mongoose/lib/model.js:3340:16)
at /home/mobileedx/WebstormProjects/passportAuthentication/node_modules/mongoose/node_modules/kareem/index.js:259:21
at /home/mobileedx/WebstormProjects/passportAuthentication/node_modules/mongoose/node_modules/kareem/index.js:127:16
at nextTickCallbackWith0Args (node.js:420:9)
at process._tickCallback (node.js:349:13)

Here is my code inside the route handler for 'localhost:3000/learn/:courseName/enroll'

  /**
  * Here If a user clicks on enroll, then the GET request will come on this page. If user is not authenticated then it
 * will redirect to the login page. If user is logged in then, user will get the courseHome page.
 */

 router.get('/learn/:courseName/enroll', isAuthenticated, function (req, res) {

  var user = req.user.username;
  var course = req.params.courseName;

  console.log('user trying to enroll is: ' + user);
  console.log('coursename user is trying to enroll is: ' + course);

  courseEnrollment.findOne({ 'courseEnrolled.courseName' :  req.params.courseName }, function(err, courseEnroll) {
      // In case of any error, return using the done method
      if (err) {
          console.log('Error in SignUp: ' + err);
          return done(err);
      }
      console.log('courseEnroll value is: ' + courseEnroll);

      courseEnroll.courseEnrolled.username.push({ "user": req.user.username});

      courseEnroll.save(function (err, data) {
          if (err)
              throw err;
          else {
              console.log('course Updated in courseEnrollment collection');
          }
      });
  });


  // When a user clicks on 'enroll' to enroll to a course, then the course name should be added in the
  // user's courseEnrolled list as well. This is what we are doing here.


  User.findOne({ 'username' :  req.user.username }, function(err, user) {
      // In case of any error, return using the done method
      if (err) {
          console.log('Error in SignUp: ' + err);
          return done(err);
      }
      console.log('user value is: ' + user);
      console.log('username value is: ' + user.username);
      user.courseEnrolled.push({ "courseName": course});

      user.save(function (err, data) {
          if (err)
              throw err;
          else {
              console.log('course Updated in user account collection');
          }
      });

      res.render('home', {user: req.user});
  });
});

Please let me know, where I am going wrong here. Can I use mongoose population to populate the username from the username field of the user collection in the courseEnrollment collection. If yes, then how to do it. Thanks.

1 Answer 1

1

From what I can guess is there is a problem with the schema. your courseEnrollment Schema. It should be like following. An array containing One object per course. which contains information about its name and the users that are enrolled in it.

   courseEnrolled: [{
           courseName : String,
           username : [{user : String}]
    }]

Hope It helps.

.................................................

ok if this is just a schema for maintaining the users who joined a particular course. Then you can follow the following schema

var courseEnrollment = new Schema({
   courseName : String:,
   usersEnrolled : [String]
}, {collection : 'courseEnrollment'});

It can be accessed in query like this.

  courseEnrollment.findOne({ 'courseName' :  req.params.courseName }, function(err, courseEnroll) {
  // In case of any error, return using the done method
  if (err) {
      console.log('Error in SignUp: ' + err);
      return done(err);
  }
  console.log('courseEnroll value is: ' + courseEnroll);

  courseEnroll.username.push({ "user": req.user.username});

  courseEnroll.save(function (err, data) {
      if (err)
          throw err;
      else {
          console.log('course Updated in courseEnrollment collection');
      }
  });

});

Sign up to request clarification or add additional context in comments.

1 Comment

Still I get the following error. events.js:141 throw er; // Unhandled 'error' event ^ TypeError: Cannot read property 'username' of undefined

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.