I am trying to add a query param to my link button in pug it should render a pre populated form of the product i want to edit but i keep getting an error in my console which says "Cannot read properties of undefined (reading 'title')" it says this for my imageUrl, price etc, But they have been defined.
admin.js
const Product = require('../models/product');
exports.getAddProduct = (req, res, next) => {
//res.render(path.join(rootDir, 'views', '/add-product.pug'))
res.render('admin/edit-product',
{pageTitle: 'Add Product',
path: '/admin/add-product',
editing: false
});
}
exports.postAddProduct= (req, res, next) => {
const title = req.body.title;
const imageUrl = req.body.imageUrl;
const price = req.body.price;
const description = req.body.description;
const product = new Product(title, imageUrl, description, price);
product.save();
res.redirect('/');
};
exports.getEditProduct = (req, res, next) => {
const editMode = req.query.edit;
if (!editMode) {
return res.redirect('/');
}
const prodId = req.params.productId;
Product.findById(prodId, product => {
if (!product) {
res.redirect('/')
}
res.render('admin/edit-product',
{pageTitle: 'Edit Product',
path: '/admin/edit-product',
editing: editMode,
product: product
});
});
};
exports.getProducts = (req, res, next) => {
Product.fetchAll((products) => {
res.render('admin/products', {
prods: products,
pageTitle: 'Admin Products',
path: '/admin/products'
});
});
}
edit-product.pug
extends ../layouts/main-layout.pug
block styles
link(rel="stylesheet", href="/css/product.css")
link(rel="stylesheet", href="/css/forms.css")
block content
main
.main-form
if editing
form(action="/admin/edit-product", method="POST")
.main-input
label(for="title") Title
input(type="text", name="title", placeholder="Search Product", value=product.title)
.main-input
label(for="imageUrl") Image URL
input(type="url", name="imageUrl", id="imageUrl", value=product.imageUrl)
.main-input
label(for="price") Price
input(type="number", name="price", id="price", step="0.01", value=product.price)
.main-input
label(for="description", value=product.description) Description
textarea(name="description", id="description", rows="5")
.main-button
if editing
button.btn(type="submit") Update Product
else
button.btn(type="submit") Add Product
else
form(action="/admin/add-product", method="POST")
.main-input
label(for="title") Title
input(type="text", name="title", placeholder="Search Product")
.main-input
label(for="imageUrl") Image URL
input(type="url", name="imageUrl", id="imageUrl")
.main-input
label(for="price") Price
input(type="number", name="price", id="price", step="0.01")
.main-input
label(for="description") Description
textarea(name="description", id="description", rows="5")
.main-button
if editing
button.btn(type="submit") Update Product
else
button.btn(type="submit") Add Product
products.pug
extends ../layouts/main-layout.pug
block styles
link(rel="stylesheet", href="/css/main.css")
link(rel="stylesheet", href="/css/card.css")
block content
main
if prods.length > 0
.grid
each product in prods
article.product-item
header.card__header
h1.product__title #{product.title}
.card__image
img(src=`${product.imageUrl}`
alt="#{product.title}")
.card__content
h2.product__price #{product.price}
p.product__description #{product.description}
.card__actions
a(href="/admin/edit-product/:product.id:?edit=true") Edit
form(action="/admin/delete-product" method="POST")
.btn
button(, type="submit") Remove
else
h1 No Product
CodePudding user response:
You are getting that response in your console because you are trying to access a property from an object that does not exist in memory.
The problem is on the object. You believe that the object is defined when that is not the case.
To fix an error like this, you look to the particular object from which you are trying to access property(ies)
I do not have an idea of your running environment but I am assuming that you a making a network call to a database to query your Products.
So, I am using native async-await to handle asynchronous calls.
If you are not making a network call, you can remove async and await wherever they occur in the code below.
Make the following modification to your request handlers:
exports.getEditProduct = async (req, res, next) => {
const editMode = req.query.edit;
if (!editMode) {
return res.redirect('/');
}
const prodId = req.params.productId;
const product = await Product.findById(prodId)
if (!product) {
res.redirect('/')
}
res.render('admin/edit-product', {
pageTitle: 'Edit Product',
path: '/admin/edit-product',
editing: editMode,
product: product
});
};
exports.getProducts = async(req, res, next) => {
const products = await Product.fetchAll({})
res.render('admin/products', {
prods: products,
pageTitle: 'Admin Products',
path: '/admin/products'
});
}
Let me know if this helped you resolve the issue.
I will be glad to assist more
CodePudding user response:
now when i do make these changes you have stated, i get an error saying
Cannot read properties of undefined (reading 'length') in my 'products.pug' file this wasnt happening before until these changes were made.
my 'products.pug' file
extends ../layouts/main-layout.pug
block styles
link(rel="stylesheet", href="/css/main.css")
link(rel="stylesheet", href="/css/card.css")
block content
main
if prods.length > 0
.grid
each product in prods
article.product-item
header.card__header
h1.product__title #{product.title}
.card__image
img(src=`${product.imageUrl}`
alt="#{product.title}")
.card__content
h2.product__price #{product.price}
p.product__description #{product.description}
.card__actions
a(href="/admin/edit-product/:product.id:?edit=true") Edit
form(action="/admin/delete-product" method="POST")
.btn
button(, type="submit") Remove
else
h1 No Product
