Cannot Read for Each property of null while displaying Gallery Images - node.js

This is my Product method for displaying all the PRODUCTS at the Home PAGE WITH respect to its Categories
//GET Products DEtails
router.get('/:category/:product',function(req,res){
var galleryImages=null;
models.Product.findOne({
where:{slug:req.params.product}
})
.then(function(product){
var galleryDir='public/product_images/' + product.id + '/gallery';
fs.readdir(galleryDir,function(files){
galleryImages=files;
res.render('product',{
title:product.title,
p:product,
galleryImages:galleryImages,
})
})
})
});
This is mine Product.ejs file for displaying it the P.Images is working above but the forEach loop is not working Cannot read property forEach of Null the Path for mine Gallery images is Correct
<% include layouts/header %>
<div class="row">
<h1 class="page-header"><%= p.title %></h1>
<div class="col-xs-12 col-md-5">
<img class="spi" src="/product_images/<%= p.id %>/<%= p.images %>" alt="">
<br>
</div>
<div class="col-xs-12 col-md-7">
<p><%= p.desc %></p>
<p>$<%= parseFloat(p.price).toFixed(2) %></p>
<p>Add To Cart</p>
</div>
<div class="col-xs-12">
<ul class="gallery">
<% galleryImages.forEach(function(images){ %>
<% if (images != "thumbs") { %>
<li>
<!--<a data-fancybox="gallery" href="/product_images/<%= p.id %>/gallery/<%= images %>"> -->
<img src="/product_images/<%= p.id %>/gallery/thumbs/<%= images %>" alt="">
</a>
</li>
<% } %>
<% }); %>
</ul>
</div>
</div>
<!--
- will gave Content Where as = will gave Html <P>tag in the Browser</P> -->
<% include layouts/footer %>

This is my products.js after try. It worked
/*
* GET product details by category
*/
router.get('/:category/:product', function (req,res){
Product.findOne({slug: req.params.product}, function (err, product) {
if(!product) { //if product not exist in db
return res.status(404).send('Product not found');
}else{
var galleryDir = 'public/product_images/' + product._id + '/gallery';
fs.readdir(galleryDir, function (err, files) {
if (err) {
console.log(err);
} else {
galleryImages = files;
res.render('product', {
title: product.title,
p: product,
galleryImages: galleryImages
});
}
});
}
});
});

Related

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.

Node w/ express using ejs: "ReferenceError: plants is not defined"

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.

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 });
});

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