1

I simply want to add another property that display course name when enrollments for a user are grabbed.

router.get('/enrollments/courses/me', auth, async (req,res)=>{
    user_id = req.user._id
    try{
        let Courses = await Enrollment.find({user_id})
        for(x in Courses){
            if(!Courses[x].course_id){
                throw new Error("No enrollments found for this student.")
            }
             courseName = await Course.findById(Courses[x].course_id)
             Courses[x].course_name = courseName.Course_Name
             console.log(Courses[x])
        }
        res.status(201).send(Courses)
    }catch(e){
        res.status(400).send(e)
    }
})

Example: Courses =

[
    {
        "_id": "607768e5e8105058546f658a",
        "user_id": "606e476107a74d49c4757c1f",
        "course_id": "60722e7392d7c6539c344a83",
        "createdAt": "2021-04-14T22:12:53.527Z",
        "updatedAt": "2021-04-14T22:12:53.527Z",
        "__v": 0
    },
    {
        "_id": "60777e7d6b2bff6040f46f58",
        "user_id": "606e476107a74d49c4757c1f",
        "course_id": "60722e8b92d7c6539c344a86",
        "createdAt": "2021-04-14T23:45:01.881Z",
        "updatedAt": "2021-04-14T23:45:01.881Z",
        "__v": 0
    },
    {
        "_id": "607787ec9f21525d644855a8",
        "user_id": "606e476107a74d49c4757c1f",
        "course_id": "60722e8392d7c6539c344a85",
        "createdAt": "2021-04-15T00:25:16.734Z",
        "updatedAt": "2021-04-15T00:25:16.734Z",
        "__v": 0
    },
    {
        "_id": "6078d78ea1ee7f05f89a3c17",
        "user_id": "606e476107a74d49c4757c1f",
        "course_id": "60722e6b92d7c6539c344a82",
        "createdAt": "2021-04-16T00:17:18.941Z",
        "updatedAt": "2021-04-16T00:17:18.941Z",
        "__v": 0
    }
]

courseName =

{
  "_id" : "60722e6b92d7c6539c344a82",
  "Course_Name" : "Course_1",
  "Description" : "This is my 1rst course",
  "__v" : 0
}

I loop through each enrollment and make another call to grab the Course name and add it to each object like so

Courses[x].course_name = courseName.Course_Name

The course name does not appear when I return Courses

I can do this :

Courses[x].course_id = courseName.Course_Name

and the course name appears for the course_id, but obviously I don't want to do that. This is how Ive added new properties to an Object before, why is this method not working?

7
  • Looks correct to me. How are you fetching this? Can you show the client side code where you observe the missing added field? Commented Apr 23, 2021 at 23:48
  • @ChristianFritz Essentially I just get the array Courses Objects return the way it displays above. the course_name property never appears. I know Im grabbing everything else correctly since I can assign courseName to an existing property in the object, but not instantiate any new ones. Commented Apr 23, 2021 at 23:56
  • silly question, but was is Courses? Are you using mongoose? Commented Apr 24, 2021 at 0:51
  • @Christian Fritz yes I'm using mongoose. That's a schema I built. Commented Apr 24, 2021 at 0:58
  • so it's not a plain object, is it? Commented Apr 24, 2021 at 1:10

2 Answers 2

1

I believe this is due to the way mongoose converts Documents to json, which is implicit when you pass the Courses object to the res.send function. If you first make the courses plain objects, you should be able to get predictable results:

  ...
  let Courses = await Enrollment.find({user_id})
  Courses = Courses.map(x => x.toJSON())
  ...

Update:

As Patryk pointed out, it seems that Mongoose provides its own mechanism for doing just that: .lean. In that case this maybe be all you need:

  let Courses = await Enrollment.find({user_id}).lean()
Sign up to request clarification or add additional context in comments.

2 Comments

I havent used mongoose in a bit, but wouldn't adding .lean() to the query be enough?
.lean() did the trick. Thank you all so much for the help.
1

As Christian & Patryk pointed out correctly,

"Courses" in your case will be an instance of mongoose.Document. You need to convert it into a native javascript object to be able to add new properties to it using -

Courses = Courses.toJSON();

or

Courses = Courses.toObject();

then you can add new property using,

Object.defineProperty(Courses[x], "course_name", {value : 'some value'});

or

Courses[x].course_name = courseName.Course_Name;

Comments

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.