Reputation: 33
I am working on a nodejs project with MongoDB for database storage and EJS for templating.
I've encountered a problem where an array of objects is not being correctly passed to EJS. The code works as expected in forums.js (and outputs as expected from console.log) but does not work correctly in forums.ejs. Upon loading the project, I am given an error: "Can not read property forEach of undefined".
Can anyone help me out here? Thank you!
forums.js
var allCategories = await dbo.getForumCategories();
allCategories.forEach(async function(category) {
category.forumArray = await dbo.getForums({categoryId: new ObjectID(category._id)});
console.log(category.forumArray); //works fine, displays as intended
});
res.render('forums.ejs', { categories: allCategories, user: req.user });
forums.ejs
<% categories.forEach(function(category) { %>
//this part works
//some code
<% category.forumArray.forEach(function(forum) { %>
//this is not working
//Can not read property forEach of undefined
<% }); %>
<% }); %>
Upvotes: 0
Views: 608
Reputation: 33
I've fixed my code by replacing the for each loop with a for loop as follows:
for (const category of allCategories) {
category.forumArray = await dbo.getForums({categoryId: new ObjectID(category._id)});
}
Upvotes: 0
Reputation: 68
In your res.render you pass categories as allCategories but I cant see where category from the ejs file is defined.
Upvotes: 0
Reputation: 4176
It's because your render
function is being called before your forEach
has finished running.
See the below example:
const foo = [1, 2, 3];
foo.forEach(async function(bar) {
bar = await mockCall() + bar;
})
console.log(foo) //> [ 1, 2, 3 ]
console.log("Are methods here running?") //> Logs correctly and demonstrates any function here would run before the `foo.forEach` is done running.
function mockCall() {
return new Promise((res, rej) => {
setTimeout(() => {
res('From the promise: ');
}, 500)
})
}
Upvotes: 1