I am having a problem with ejs templates. I've already worked with it in another project and it worked but in this one it doesn't seem to work all it shows is a blank page and it does not render the cards with the passed data. Here is my "view products" route code and my html code for "viewproducts.ejs".
view products route:
app.get('/viewproducts', function (req, res) {
var names = [];
var prices = [];
var descriptions = [];
var product = [];
var length;
Product.find(function (err, products) {
if (err) {
console.log(err);
} else {
length = products.length;
names = products.map(function (i) {
return i.name;
});
prices = products.map(function (i) {
return i.price;
});
descriptions = products.map(function (i) {
return i.description;
});
}
for (var i = 0; i < length; i ) {
product.push({
name: names[i],
description: descriptions[i],
price: prices[i],
});
}
console.log(product);
});
res.render('viewproducts', { artisanproduct: product });
});
viewproducts.ejs
<body>
<% artisanproduct.forEach((product)=>{ %>
<div>
<div class="card-body">
<div class="row">
<div class="col-lg-3">
<img class="w-100"src="" alt="">
</div>
<div class="col-lg-9">
<h5 class="card-title"><%=product.name%></h5>
<p class="card-text"><%=product.description%></p>
</div>
</div>
<h2><%=product.price%><span>MAD</span></h2>
<button type="submit">BUY</button>
</form>
</div>
</div>
</div>
<%})%>
</body>
CodePudding user response:
You are calling res.render()
BEFORE you've collected any data for it. Product.find()
is non-blocking and asynchronous. So, to use its result, your code has to be inside its callback or in a function you call from that callback. Change and simplify to this:
app.get('/viewproducts', function (req, res) {
Product.find(function (err, products) {
if (err) {
console.log(err);
res.sendStatus(500); // send error response
return;
}
const product = products.map(item => {
return {
name: item.name,
price: item.price,
description: item.description
};
});
res.render('viewproducts', { artisanproduct: product });
});
});
Summary of changes:
- Move
res.render()
inside theProduct.find()
callback so it has access to that data. - Build product array in one
.map()
instead of many. - Send error response when there's an error.
- Use
const
orlet
instead ofvar
. - Remove unnecessary temporary arrays and temporary variables.