Reputation: 63
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?
Upvotes: 1
Views: 754
Reputation: 503
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;
Upvotes: 1
Reputation: 21364
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()
Upvotes: 1