I am new to nodeJs and wanted to practice creating a shopping cart. I all succeeded alone but managed to display the detail of products clicked by the user that it does not work: SUMMARY OF MY CODE
I created in my models folder two js files called user.js and jacket.js which each contain a schema and model separately. In my Controllers folder, I have an index.js file which includes:
const User = require ("../models/users")
const Jacket = require ('../models/jacket')
My question is that I want to access the Id of these two documents at the same time: Here is my code
const getProductId = (req, res, next) =>{
const id = req.params.id
Promise.all([User.findById(id).exec(), Veste.findById(id).exec() ])
.then(([product]) => {
// Or however your template might look like
res.render('product-detail', { product} )
})
.catch(error =>{
console.log(error)
})
}
My routes folder:
const express = require ('express')
const router = express.Router ()
const getIndexController = require ('../controllers/index')
router.get ('/product/:id', getIndexController.getProductId)
this only works for user but not for jacket Here is my code in my ejs file:
<h1> <% = product.name%> </h1>
<img width = "200px" height = "200px" src = "<% = product.image%>" alt = "<% =
product.image%>" />
<h1> <% = product.description%> </h1> <h1> <% = product.prix%> </h1>
with user it works well but for jacket it gives me back:
TypeError: D:\afrikolor\views\product-detail.ejs:8
6| </head>
7| <body>
>> 8| <h1><%= product.name %></h1>
9| <img width="200px" height="200px" src="<%= product.image %>" alt="<%= product.image %>"/>
10| <h1><%= product.description %></h1>
11| <h1><%= product.prix %></h1>
Cannot read property 'name' of null
at eval (D:\afrikolor\views\product-detail.ejs:12:34)
at product-detail (D:\afrikolor\node_modules\ejs\lib\ejs.js:691:17)
at tryHandleCache (D:\afrikolor\node_modules\ejs\lib\ejs.js:272:36)
at View.exports.renderFile [as engine] (D:\afrikolor\node_modules\ejs\lib\ejs.js:489:10)
at View.render (D:\afrikolor\node_modules\express\lib\view.js:135:8)
at tryRender (D:\afrikolor\node_modules\express\lib\application.js:640:10)
at Function.render (D:\afrikolor\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (D:\afrikolor\node_modules\express\lib\response.js:1012:7)
at D:\afrikolor\controllers\index.js:361:11
at processTicksAndRejections (internal/process/task_queues.js:94:5)
Remove square bracket surrounding ‘product’ variable. Promise.all returns array implicitly and you make it another array inside an array.
Try like this.
.then((product) =>
thank you for your reply
it seems to work but when I click on a product to see the detail:
the page is completely blank
Because, you are sending data to the html page named product which holds array inside. In the html page you are trying to access the array as if it was an object.
Inside html page,
Either you send data to the html page as object , or you get single item from product array. Such,
Thank you again you are absolutely right but for Jacket it works but for User it gives me this:
TypeError: D: \ afrikolor \ views \ product-detail.ejs: 10
8 |
9 |
>> 10 | <h1> <% = product [1] .name%> </h1>
11 | <img width = "200px" height = "200px" src = "<% = product [1] .image%>" alt = "<% = product [1] .image%>" />
12 | <h1> <% = product [1] .description%> </h1>
13 | <h1> <% = product [1]. price%> </h1>
Cannot read property 'name' of null
at eval (D: \ afrikolor \ views \ product-detail.ejs: 12: 37)
at product-detail (D: \ afrikolor \ node_modules \ ejs \ lib \ ejs.js: 691: 17)
at tryHandleCache (D: \ afrikolor \ node_modules \ ejs \ lib \ ejs.js: 272: 36)
at View.exports.renderFile [as engine] (D: \ afrikolor \ node_modules \ ejs \ lib \ ejs.js: 489: 10)
at View.render (D: \ afrikolor \ node_modules \ express \ lib \ view.js: 135: 8)
at tryRender (D: \ afrikolor \ node_modules \ express \ lib \ application.js: 640: 10)
at Function.render (D: \ afrikolor \ node_modules \ express \ lib \ application.js: 592: 3)
at ServerResponse.render (D: \ afrikolor \ node_modules \ express \ lib \ response.js: 1012: 7)
at D: \ afrikolor \ controllers \ index.js: 362: 11
at processTicksAndRejections (internal / process / task_queues.js: 94: 5)
Does individual item inside product array include user information ?
If so , I 'm guessing the structure like this…
product : [
{
image: ....,
description...,
price...
user: { name : ..., such info}
},
{
..2nd item
}
]
So you can not directly access name on product[1].
Because its a whole object without name property on it.
product[1].user.name
Could be the right answer.
No, I created two different collections in my models folder, one called User:
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
name:{
type: String,
},
description:{
type: String,
},
picture:{
type: String
},
price:{
type: String,
}
})
const User = new mongoose.model('User', userSchema)
module.exports = User
The other one called jacket:
const mongoose = require ('mongoose')
const userSchema = new mongoose.Schema ({
name: {
type: String,
},
description:{
type: String,
},
picture:{
type: String
},
price:{
type: String,
}
})
const Jacket = new mongoose.model ('Jacket', userSchema)
module.exports = Jacket
in fact they are different files that I imported
const User = require ("../models/users")
const Jacket = require ('../models/jacket')
I see… but what is Veste ? You are not supposed to be calling it by model name Jacket ?
Jacket.findById(id).exec()
if I made a mistake by copying the word in French I corrected it sorry I am French speaking
I see no problem… Well, just try to access data inside User html page as product[0] and Jacket is the same as product[1].
If it sucks for product [0] .name
But the problem when I go to the jacket page and click on a product it gives me:
TypeError: D: \ afrikolor \ views \ product-detail.ejs: 10
8 |
9 |
>> 10 | <h1> <% = product [0] .name%> </h1>
11 | <img width = "200px" height = "200px" src = "<% = product [0] .image%>" alt = "<% = product [0] .image%>" />
12 | <h1> <% = product [0] .description%> </h1>
13 | <h1> <% = product [0]. price%> </h1>
Cannot read property 'name' of null
at eval (D: \ afrikolor \ views \ product-detail.ejs: 12: 37)
at product-detail (D: \ afrikolor \ node_modules \ ejs \ lib \ ejs.js: 691: 17)
at tryHandleCache (D: \ afrikolor \ node_modules \ ejs \ lib \ ejs.js: 272: 36)
at View.exports.renderFile [as engine] (D: \ afrikolor \ node_modules \ ejs \ lib \ ejs.js: 489: 10)
at View.render (D: \ afrikolor \ node_modules \ express \ lib \ view.js: 135: 8)
at tryRender (D: \ afrikolor \ node_modules \ express \ lib \ application.js: 640: 10)
at Function.render (D: \ afrikolor \ node_modules \ express \ lib \ application.js: 592: 3)
at ServerResponse.render (D: \ afrikolor \ node_modules \ express \ lib \ response.js: 1012: 7)
at D: \ afrikolor \ controllers \ index.js: 362: 11
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal / process / task_queues.js: 94: 5)
Couldn't we combine the two
example:
<h1> <% = product [0] [1] .name%> </h1>
because jacket and user they have their own page and I try by their Id to display the product detail on one page
You use this syntax for multidimensional array, which you don’t
want to use it here.
ahmadanote26:
product [0] [1]
Did you use product[0] for user details, and product[1] for jacket details, and still not works ? Make sure you have Jacket and User data coming from database.
sorry but I understood the code correctly:
product [0] for user details, and product [1] for jacket details
where will he be
To make everything clear just change this block of code to…
ahmadanote26:
const getProductId = (req, res, next) =>{
const id = req.params.id
Promise.all([User.findById(id).exec(), Veste.findById(id).exec() ])
.then(([product]) => {
// Or however your template might look like
res.render('product-detail', { product} )
})
.catch(error =>{
console.log(error)
})
}
…this.
const getProductId = async (req, res, next) =>{
const id = req.params.id
try {
const user = await User.findById(id);
const jacket = await Jacket.findById(id);
res.render('product-detail', { user, jacket } )
}catch(error =>{
console.log(error)
})
}
If both user and jacket variable not null, which means you collect data from database without problem. Then, inside product-detail html use user variable for accesing its properties, jacket for its properties.
frankly I'm sorry to tire you
But I believe the problem is in the html part
because we use two different files
Now my question is what we could do in the HTML part to associate {user, jacket}
in 'product-detail'
<% if(user) {%>
<h1><%= user.name %></h1>
<img width="200px" height="200px" src="<%= user.image %>" alt="<%= user.image %>"/>
<h1><%= user.description %></h1>
<h1><%= user.prix %></h1>
<%} else if(jacket) {%>
<h1><%= jacket.name %></h1>
<img width="200px" height="200px" src="<%= jacket.image %>" alt="<%= jacket.image %>"/>
<h1><%= jacket.description %></h1>
<h1><%= jacket.prix %></h1>
<%} %>
I succeeded by doing
1 Like
No problem at all.
Well, I don’t know how you structure product-detail html page, but simply
you can use same html elements for the both sources. Such,
1 Like
Honestly I don’t know how to thank you all day you helped me a big thank you you are a good developer
if you do tutorials please share me especially with nodejs
I’m glad you solved the problem. Don’t mention about it , we all here to help eachother.
If you stuck you know where to find us
1 Like