Javascript NodeJS:购物车是如何定义的?
我正在使用一个电子商务应用程序,我继续遇到以下错误:Javascript NodeJS:购物车是如何定义的?,javascript,node.js,Javascript,Node.js,我正在使用一个电子商务应用程序,我继续遇到以下错误: (节点:71376)未处理的PromisejectionWarning:ReferenceError:未定义购物车 这里如何定义购物车 const express = require("express"); const cartsRepo = require("../repositories/carts"); const { Router } = require("express")
(节点:71376)未处理的PromisejectionWarning:ReferenceError:未定义购物车
这里如何定义购物车
const express = require("express");
const cartsRepo = require("../repositories/carts");
const { Router } = require("express");
const productsRepo = require("../repositories/products");
const cartShowTemplate = require("../views/carts/show");
const router = express.Router();
// Receive a post request to add an item to a cart
router.post("/cart/products", async (req, res) => {
console.log(req.body.productId);
// Figure out the cart!
try {
let cart;
if (!req.session.cartId) {
// // we dont have a cart, we need to create one,
// // and store the cart id on the req.session.cartId property
cart = await cartsRepo.create({ items: [] });
req.session.cartId = cart.id;
} else {
// // We have a cart! Lets get it from the repository
cart = await cartsRepo.getOne(req.session.cartId);
}
const existingItem = cart.items.find(
(item) => item.id === req.body.productId
);
if (existingItem) {
// increment quantity and save cart
existingItem.quantity++;
} else {
// add new product id to items array
cart.items.push({ id: req.body.productId, quantity: 1 });
}
await cartsRepo.update(cart.id, {
items: cart.items,
});
} catch (error) {
console.log(error);
}
res.send("Product added to cart");
});
// Receive a GET request to show all items in cart
router.get("/cart", async (req, res) => {
try {
if (!req.session.cartId) {
return res.redirect("/");
}
const cart = await cartsRepo.getOne(req.session.cartId);
for (let item of cart.items) {
const product = await productsRepo.getOne(item.id);
item.product = product;
}
} catch (error) {
console.log(error);
}
res.send(cartShowTemplate({ items: cart.items }));
});
// Receive a post request to delete an item from a cart
module.exports = router;
这是carts.js
文件:
const Repository = require("./repository");
class CartsRepository extends Repository {}
module.exports = new CartsRepository("carts.json");
该JSON文件具有:
[
{
"items": [],
"id": "d068d19a"
},
{
"items": [],
"id": "7fb21ae7"
},
{
"items": [],
"id": "fa6af1d1"
},
{
"items": [],
"id": "e64012d9"
},
{
"items": [],
"id": "77ebb5ed"
},
{
"items": [],
"id": "b68686f0"
},
{
"items": [],
"id": "977eded8"
},
{
"items": [],
"id": "5601d00b"
},
{
"items": [],
"id": "d10c8afd"
},
{
"items": [],
"id": "82e18133"
},
{
"items": [
{
"id": "",
"quantity": 5
}
],
"id": "05b757b9"
}
]
我确实尝试过放置res.send(cartShowTemplate({items:cart.items}))代码>在try/catch
中,如下所示:
// Receive a GET request to show all items in cart
router.get("/cart", async (req, res) => {
try {
if (!req.session.cartId) {
return res.redirect("/");
}
const cart = await cartsRepo.getOne(req.session.cartId);
for (let item of cart.items) {
const product = await productsRepo.getOne(item.id);
item.product = product;
}
res.send(cartShowTemplate({ items: cart.items }));
} catch (error) {
console.log(error);
}
});
然后我得到了这个错误:
TypeError: Cannot read property 'title' of undefined
(node:71588) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'title' of undefined
这与我在视图/show.js中的内容有关:
const layout = require("../layout");
module.exports = ({ items }) => {
const renderedItems = items
.map((item) => {
return `
<div>${item.product.title} - ${item.product.price}</div>
`;
})
.join("");
return layout({
content: `
<h1>Cart</h1>
${renderedItems}
`,
});
};
但当我点击购物车链接进入购物车菜单时,仍然会出现以下错误:
TypeError: Cannot read property 'title' of undefined
(node:71588) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'title' of undefined
在router.get(“/cart”…
route handler中,您将cart
定义为try
块内的const
。const
变量是块范围的,因此您可以将其仅存在于块内。您可以尝试在块外使用它,包括:
res.send(cartShowTemplate({items:cart.items}));
如果要在此处使用常量,则需要在try块外部声明变量,或将res.send
移动到块内部
下面是一个最简单的例子来说明这个问题:
试试看{
const cart=“某些值”
}捕获(错误){
console.log(错误);
}
log(购物车类型)
正如Mark Meyer指出的那样,使用const
将变量范围限定到包含的块
您可以在购物车位于范围内的try块内执行res.send()
,如下所示:
/。。。
//接收GET请求以显示购物车中的所有项目
路由器.get(“/cart”),异步(请求,res)=>{
试一试{
如果(!req.session.cartId){
返回res.redirect(“/”);
}
const cart=wait cartsRepo.getOne(req.session.cartId);
用于(出租购物车的项目。项目){
const product=wait productsRepo.getOne(item.id);
item.product=产品;
}
res.send(cartShowTemplate({items:cart.items}));
}捕获(错误){
console.log(错误);
}
});
// ...
此外,我建议使用Promise.all
为每个项目填充产品。这将同时启动产品请求并加快请求速度:
/。。。
const cart=wait cartsRepo.getOne(req.session.cartId);
const items=wait Promise.all(cart.items.map)(异步项=>({
…项目,
产品:等待产品采购单(item.id),
})))
res.send(cartShowTemplate({items}));
// ...
编辑…解决未定义的item.product.title的第二个问题。
这里的问题是,您试图在for in
循环中变异项
,但是,for in
循环正在循环中创建一个新的项
对象,因此您没有变异外部数组。下面的示例显示了该问题
let items=[{test:1},{test:2}];
for(将项目放入项目中){
item.product=`product${item.test}`
}
console.log(items);
上面关于try/catch
块的答案是正确的,但是我继续得到错误,不是因为编程逻辑,而是因为两件事
在layout.js的内部
我缺少href
上的/cart
:
<div class="navbar-item">
<a href="/cart"><i class="fa fa-shopping-cart"></i> Cart</a>
</div>
@Daniel,现在这个问题似乎有多个独立的问题。另外,请检查我的答案,它解决了您提出的两个问题。@dillon,我尝试了您的解决方案,但仍然得到无法读取未定义的属性“title”
您使用了承诺。所有的?如果是,我建议记录结果因为它可能没有返回您想要的内容。@dillon,我得到的产品未定义