Node w/ express using ejs: "ReferenceError: plants is not defined" - node.js

I'm getting this error in my when I load my .ejs view:
ReferenceError: plants is not defined
All of my other views work with the includes and such.
plants.js router:
router.get('/plants', plantsController.getPlantsPage);
plants.js controller:
const Plant = require('../models/plant');
exports.getPlantsPage = (req, res, next) => {
res.render('plants', {
plants: plants,
pageTitle: 'Plants',
path: '/plants',
hasPlants: plants.length > 0
});
};
plant.js model:
module.exports = class Plant {
constructor(common_name, image_url, scientific_name) {
this.common_name = common_name;
this.image_url = image_url;
this.scientific_name = scientific_name;
}
}
plants.ejs:
<% if (hasPlants) { %>
<% for (let plant of plants) { %>
<div class="col s12 m4">
<div class="card">
<div class="card-image waves-effect waves-block waves-light">
<img class="activator" src="<%= plant.image_url %>">
</div>
<div class="card-content">
<span class="card-title activator grey-text text-darken-4"><%= plant.common_name %><i class="material-icons right">MORE</i></span>
</div>
<div class="card-reveal">
<span class="card-title grey-text text-darken-4"><%= plant.common_name %><i class="material-icons right">CLOSE</i></span>
<p><%= plant.scientific_name %></p>
<p>Plant Details</p>
</div>
</div>
</div>
<% } %>
<% } else { %>
<div class="row">
<div class="col s12">
<p>No Plants Added!</p>
</div>
</div>
<% } %>
Thanks.

Did you make sure you set the plants variable? The error says plants is not defined. Try console.log() the variable.

Related

error in nodejs using sripe for payment for website

I am implementing a payment method in my e-commerce website using stripe and node.js , and I am not using a database only using JSON files to add my items to the website, but I am getting errors in ejs file. for rendering the page I used the fs module in node js. I wanted to know where I can define the items in ejs , or server , or HTML file
''' shop.ejs'''
<div class="box-container">
<% items.products.forEach(function(item){ %>
<div class="box" data-item-id="<%= item.id %>">
<div class="icons">
</div>
<img class="image" src="/image/<%= item.imgName %>" alt="">
<div class="content">
<div class="price"> &#8377 <%= item.price %></div>
<h3 class="shop-item-title"><%= item.name %></h3>
<div class="stars">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="far fa-star"></i>
<span> (50) </span>
</div>
</div>
</div>
<% }) %>
'''server.js'''
app.get('/shop', function(req, res){
fs.readFile('items.json', function(error, data){
if(error){
res.status(500).end()
}else {
res.render('shop.ejs', {
items: JSON.parse(data)
})
}
})
})
'''error'''
>> 172| <% items.products.forEach(function(item){ %>
173| <div class="box-container" data-item-id="<%= item.id %>">
174| <div class="box">
175| <div class="icons">
items are not defined
Did you pass the items data object to the ejs render function?

Error: Could not find matching close tag for "<%"

<% if (users.length > 0) { %>
<div class="grid">
<% for(user of users) { %>
<article class="card product-item">
<header class="card__header">
<h1 class="product__title">user.Username</h1>
</header>
<div class="card__actions">
<button class="btn">Go to profile</button>
</div>
</article>
<% } %>
</div>
<% } else { %>
<h3>No users are registered yet!</h3>
<% } %>
Inside the if statement > (greater than) sign is recognizing as closing tag. What should I do?
There are no syntax errors in the code supplied when tested using the following code (question code is contained in the template variable):
const ejs = require('ejs');
let template = `
<% if (users.length > 0) { %>
<div class="grid">
<% for(user of users) { %>
<article class="card product-item">
<header class="card__header">
<h1 class="product__title">user.Username</h1>
</header>
<div class="card__actions">
<button class="btn">Go to profile</button>
</div>
</article>
<% } %>
</div>
<% } else { %>
<h3>No users are registered yet!</h3>
<% } %>
`;
const renderData = {
users: [{
Username: 'test'
}]
};
const output = ejs.render(template, renderData);
console.log(output);
Console output:
<div class="grid">
<article class="card product-item">
<header class="card__header">
<h1 class="product__title">user.Username</h1>
</header>
<div class="card__actions">
<button class="btn">Go to profile</button>
</div>
</article>
</div>
However, as noted by #eol, user.Username should be wrapped in output tags.

Why is my JS logic appearing on index (using ejs/express)

im having an issue understanding why my JS is appearing on my layout. Im currently following along with a tutorial on sitepoint creating forms with in express and when i render the layout.ejs + index.ejs with contact as a partial, the logic on partial is appearing on the page as text.
here is the code:
<div class="form-header">
<% if (Object.keys(errors).length === 0) { %>
<h2>Send us a message aa</h2>
<% } else { %>
<h2 class="errors-heading">Oops, please correct the following:</h2>
<ul class="errors-list">
<% Object.values(errors).forEach(error => { %>
<li><%= error.msg %></li>
<% }) %>
</ul>
<% } %>
</div>
<form method="post" action="/contact" novalidate>
<div class="form-field <%= errors.message ? 'form-field-invalid' : ''
%>">
<label for="message">Message</label>
<textarea class="input" id="message" name="message" rows="4"
autofocus><%= data.message %></textarea>
<% if (errors.message) { %>
<div class="error"><%= errors.message.msg %></div>
<% } %>
</div>
<div class="form-field <%= errors.email ? 'form-field-invalid' : '' %>">
<label for="email">Email</label>
<input class="input" id="email" name="email" type="email" value="<%=
data.email %>" />
<% if (errors.email) { %>
<div class="error"><%= errors.email.msg %></div>
<% } %>
</div>
<div class="form-actions">
<button class="btn" type="submit">Send</button>
</div>
</form>

EJS: Failed to load resource: the server responded with a status of 500 (Internal Server Error) using loop

I am trying to loop through my portfolio sections while inputting it with ejs. But it is throwing a 500 error. I created the loop to code less. The other pages work fine, but the title can't be found or the path is lost. It worked before I added the loop.
const express = require('express');
const router = express.Router();
/* GET portfolio page. */
router.get('/portfolio', (req, res, next) => {
let recentProjects = [{
title: 'ASL Logo',
paragraph: 'Re-branding of ASL Water Solutions'
},
{
title: 'Siva Creative Business Card',
paragraph: 'Re-branding of Siva Creative'
},
{
title: 'Encore Renovations',
paragraph: 'Website design for Encore'
}
]
res.render('portfolio', {
projects: recentProjects
});
});
module.exports = router;
<% include partials/header %>
<section class="content-section" id="portfolio">
<div class="container">
<div class="content-section-heading text-center">
<h3 class="text-secondary mb-0">
<%= title %>
</h3>
<h2 class="mb-5">Recent Projects</h2>
</div>
<div class="row no-gutters">
<% for(let i = 0; i < projects.length; i++) { %>
<div class="col-lg-6">
<a class="portfolio-item">
<span class="caption">
<span class="caption-content">
<h2><%= projects[i].title %></h2>
<p class="mb-0"><%= projects[i].paragraph %></p>
</span>
</span>
<img class="img-fluid" src="img/portfolio-1.jpg" alt="">
</a>
</div>
<% } %>
</div>
</div>
</section>
<% include partials/footer %>
In your view, the variable title is not defined, you should pass it to the view just as you do for the recentProjects object:
res.render('portfolio', {
projects: recentProjects,
title: 'portfolio'
});

showing MongoDB document value to EJS in a loop

I'm working on a node project. And node is very new to me so sorry if I ask a lot of stupid questions.
I'm trying to show all of my topics on my index.ejs. The root file already shows them in the console log but I can't seem to get them to show in the view.
The view already loops and knows that there are 2 topics, but the content is empty.
This is my code from the routes/index.js
router.get('/', function(req, res, next) {
Topic.find({}).exec(function(err, topic)
{
if(err){
console.log('There ware no topics');
return next(err)
}
else
{
console.log('Whoop whoop there are some topics');
res.render('index', { topic: topic } );
console.log("Logging data: " + topic);
console.log("Loggin data title out db: " + topic.topicTitle);
console.log("Loggin data desc out db: " + topic.topicDescription);
console.log("Loggin data date out db: " + topic.topicDateCreated);
}
});
});
module.exports = router;
And here is how I try to show it in my views/index.ejs
<ul>
<% for(var i = 0; i < topic.length; i++) {%>
<li>
<div class="post animated fadeInLeft">
<div class="wrap-ut pull-left">
<div class="userinfo pull-left">
<div class="avatar">
<img src="images/avatar.jpg" alt="default avatar" />
<p class="moderator"> <%= topic.fbUsername %> </p>
</div>
</div>
<div class="posttext pull-left">
<h2 class="topictitle"><a href="/topicdetail/{topic_id}" <%= topic.topicTitle %> </a></h2>
</div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
</li>
<% } %>
</ul>
The topic variable is an array, so you need to pass the index in order to get the proper Topic document. For instance:
<%= topic[i].fbUsername %>
Your view should look like:
<ul>
<% for(var i = 0; i < topic.length; i++) {%>
<li>
<div class="post animated fadeInLeft">
<div class="wrap-ut pull-left">
<div class="userinfo pull-left">
<div class="avatar">
<img src="images/avatar.jpg" alt="default avatar" />
<p class="moderator"> <%= topic[i].fbUsername %> </p>
</div>
</div>
<div class="posttext pull-left">
<h2 class="topictitle"> <%= topic[i].topicTitle %> </h2>
</div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
</li>
<% } %>
</ul>
UPDATE
You also forgot to close the tag here:
--------------------------------------------------------↴
<h2 class="topictitle"><a href="/topicdetail/{topic_id}" <%= topic[i].topicTitle %> </a></h2>
Closing the tag, I was able to see the titles:
<h2 class="topictitle"> <%= topic[i].topicTitle %> </h2>

Resources