a property is not defined ejs: nodejs - node.js

I was following a tutorial and got stuck here. Everything looks ok to me. Still I am getting this error. Can some one point me to the right direction.
memberName is not defined
<% for(var i=0; i < notes.length; i++) { %>
<div class="list-group-item">
<div>Note from <em><strong><%=memberName[i]%></strong></em> on:
<%= createdOn.toDateString() %>
<strong><%= project[i] %></strong></div>
<div><strong>Work yesterday:</strong>
<%= workYesterday[i] %>
</div>
<div><strong>Work today:</strong>
<%= workToday[i] %>
</div>
<div><strong>Impediment:</strong>
<%= impediment[i] %>
</div>
</div>
<%}%>
Controller code:
exports.list = function (req, res) {
var query = Standup.find();
query.limit(12)
.exec(function (err, results) {
console.log(results);
res.render('index', { title: 'Standup - List', notes: results });
});
};

<%=memberName[i]%> in the ejs file mean "when I ll send the ejs, I ll replace that by the value of memberName".
But in your controller, you don t provide it, which block ejs.
In the controller, you should have something like:
res.render('index', {
title: 'Standup - List',
notes: results,
memberName: memberName //<--
});
When this one will be fixed, you ll also have to provide createdOn, project, workYesterday, workToday, workTomorrow and impediment.

<%= is a EJS tag for evaluating values in HTML.
<%= memberName %> will output the value of variable memberName in your HTML code. Thus you need to pass the parameter memberName while you are rendering the html page. You have missed out the parameter.
Your controller code should look like:
exports.list = function (req, res) {
var query = Standup.find();
query.limit(12)
.exec(function (err, results) {
console.log(results);
res.render('index', { title: 'Standup - List', notes: results, memberName: 'Test Member Name' });
});
};

You're probably looking for this:
<% for(var i=0; i < notes.length; i++) { %>
<div class="list-group-item">
<div>Note from <em><strong><%= notes[i].memberName %></strong></em> on:
<%= notes[i].createdOn.toDateString() %>
<strong><%= notes[i].project %></strong></div>
<div><strong>Work yesterday:</strong>
<%= notes[i].workYesterday %>
</div>
<div><strong>Work today:</strong>
<%= notes[i].workToday %>
</div>
<div><strong>Impediment:</strong>
<%= notes[i].impediment %>
</div>
</div>
<%}%>
Which can be further reduced to this:
<% notes.forEach(function(note) { %>
<div class="list-group-item">
<div>Note from <em><strong><%= note.memberName %></strong></em> on:
<%= note.createdOn.toDateString() %>
<strong><%= note.project %></strong></div>
<div><strong>Work yesterday:</strong>
<%= note.workYesterday %>
</div>
<div><strong>Work today:</strong>
<%= note.workToday %>
</div>
<div><strong>Impediment:</strong>
<%= note.impediment %>
</div>
</div>
<% }) %>

Related

File type:ejs.I have a problem with syntacxis

<ul>
<% if ('contacts'.length) { %> <% 'contacts'.forEach(({ link, name }) => { -%>
<li>
<%= name %>
</li>
<% }) %> <% } %>
</ul>
I have a syntacxis problem with this part of ejs file.What would be the correct syntax?
I try ejslint,but he doesnt support me

Why won't ejs loop through/recognize my data pulled from the mongodb schema?

I'm trying to loop through the products in my products db and display each product as its own card on my site. The db contains 2 items and they won't show up on the page, however, the items do show up in the console when I console log them.
Here is my controller code:
exports.getShop = (req, res, next) => {
Product.find(products => {
res.render('shop/shop',{
products: products,
path:'/shop',
pageTitle:'Shop'
})
})
.then(products => {
console.log(products);
})
.catch(err => {
console.log(err);
})};
Here is my html/ejs:
<% if (products) { %>
<div class="grid">
<% for (let product of products) { %>
<article class="card product-item">
<header class="card__header">
<h1 class="product__title">
<%= product.title %>
</h1>
</header>
<div class="card__image">
<img src="/<%= product.image %>" alt="<%= product.title %>">
</div>
<div class="card__content">
<h2 class="product__price">$
<%= product.price %>
</h2>
<p class="product__description">
<%= product.description %>
</p>
</div>
</article>
<% } %>
</div>
<% } else { %>
<h1>No Products Found!</h1>
<% } %>
Like I said, the console will display the products in my db but the page output is "No Products Found!" If I change the code a bit I get an error loading the page at "products.length"
modified code:
<% if (products.length > 0 ) { %>
<div class="grid">
<% for (let product of products) { %>
The error says "Cannot read property of null".
What am I missing here?
Product.find(query).toArray().then(products => {
res.render('shop/shop',{
products: products,
path:'/shop',
pageTitle:'Shop'
})
The issue is that the mongo node.js drivers' find function returns a cursor object, so to 'promisify' it you'll need to use the .toArray() function that returns a promise.

Cannot read property 'name' of null error

I'm still a baby on web development. I am getting the following error, can
anyone help me?
Schema:
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
_id: String
});
var Campground = mongoose.model("Campground", campgroundSchema);
app.get("/campgrounds/:id",function(req , res){
Campground.findById(req.params.id, function(err, foundCampgrounds){
if(err){
console.log(err);
}else{
res.render("show", {campground: foundCampgrounds});
}
});
});
This is the index.ejs template:
<div class="row text-center" style="display:flex; flex-wrap:wrap">
<% campgrounds.forEach(function(campground){ %>
<div class="col-md-3 col-sm-6">
<div class="thumbnail">
<img src="<%= campground.image %>">
<div class="caption">
<h4> <%= campground.name %> </h4>
</div>
<p><a href="/campgrounds/ <%= campground._id %>"
class="btn btn-primary">More Info</a>
</p>
</div>
</div>
<% }) %>
</div>
show.ejs:
<%- include('partials/header')%>
<h1>this is a show template</h1>
<p><%= campground.name %></p>
<%- include('partials/footer')%>
TypeError:
Cannot read property 'name' of null
You should check if campground is defined at all - you can either do that in your nodejs-controller or in your template. Here's an example for ejs:
<%- include('partials/header')%>
<% if (campground) { %>
<h1>this is a show template</h1>
<p><%= campground.name %></p>
<% } else { %>
<h1>No camground data was found</h1>
<% } %>
<%- include('partials/footer')%>
On the index.ejs. Use a span to retrieve the _id from the
DB, as follows
<span> <%= campground._id %> </span>
Why? Because _id is a unique object and is auto-generated. No need to even
include it on the Schema unless you want to create it yourself on which case
you'll then amend the controller with a variable. I struggled with this but now
okay.

I want to redirect to another page when user click image

i created a gallery and i want when user click a image then it will redirect to another page as well as new page display full details of that particular image ! how to do it in node js and mongoDB.
This is my index.ejs page where i displayed my images.
<% if(files) { %>
<% files.forEach(function(file) { %>
<div class="card card-body mb-3">
<% if(file.isImage){ %>
<img src="image/<%=file.filename %>" alt="" >
<span><%= file.metadata.username %></span><br>
<span><%= file.metadata.age %></span>
<% } else {%>
<p>Error</p>
<% } %>
</div>
<% }) %>
<% } else { %>
<p>No files to show </p>
<% } %>
route file
app.get('/checkout/:filename', (req,res) => {
res.redirect('/solo', { pic: req.params.filename });
});

How to array of objects in template ejs?

I have a results variable that is an array of objects. I carry the results variable from my javascript file to my main route file. I am trying to render my page to display lists of each object in my template ejs file. I am able to list everything fine, but the lists are coming out as [object object] instead of the actual words that are in the objects. How do I get this to display as strings in my template file?
This is my route file:
app.get('/announcement', function(req,res){
var getAnnouncements = require('../public/javascripts/announcement.js'); //Load the module, get the name of the script file
//define the functions here
var onSpreadsheetSuccess = function (results) { //result is announcementArray
//add results list to template);
res.render('announcement', {title: "Announcement page", results: results});
}
getAnnouncements.loadSheet(onSpreadsheetError, onSpreadsheetSuccess); //call the function from script with the parameters passed
})
This is what I am doing in my template ejs file:
<ul>
<% results.forEach(function(result){ %>
<li><%= result %></li>
<% }); %>
</ul>
<ul>
<% for(var i=0; i<results.length; i++) { %>
<li>
<%= results[i] %>
</li>
<% } %>
</ul>
This will show list of id of your results, just change _id by your property of objects as you want to show.
<ul>
<% results.map((result)=>{ %>
<li>
<%= result._id %>
</li>
<% }) %>
</ul>
My answer is as follows. I changed one line from the answer by other person.
<ul>
<%for (var result in results){%>
<li><%=result%>:<%=results[result]%></li>
<%}%>
</ul>
With modern JS it can be simplified to
<ul>
<% for (var result of results) { %>
<li>
<%= result %>
</li>
<% } %>
</ul>
You should be fine with this:
<ul>
<% for(let i = 0; i < results.length; i++){ %>
<li><%= results[i].title %></li>
<% } %>
</ul
or when you rather like to use the forEach:
<ul>
<% results.forEach( function (result) { %>
<li><%= result.title %></li>
<% }) %>
</ul
the object you push(ed) into your array:
const result = {
title: anyTitle,
input: anyInput
}
Try this:
<ul>
<%for (var result in results){%>
<li><%=result%></li>
<%}%>
</ul>

Resources