前端更新购物车项总价返回NaN,price参数未定义问题排查
购物车更新数量时总价返回NaN,price未定义的解决问题
我在购物车页面更新商品数量时,自动刷新商品总价始终返回NaN,控制台日志显示price未定义,求解决办法。
脚本
function updateCartItem(cartId, cartItemId, quantityToAdd, csrftoken, price) { console.log('price:', price); fetch(`/api/carts/${cartId}/items/${cartItemId}/`, { method: "PATCH", headers: { "Content-Type": "application/json", "X-CSRFToken": csrftoken, }, body: JSON.stringify({ quantity: quantityToAdd, }), }) .then((response) => response.json()) .then((data) => { console.log("Cart successfully updated:", data); console.log("CART:", cartId) fetch("/cart/") .then((response) => response.text()) .then((html) => { // 更新页面上的购物车商品和总价 const parser = new DOMParser(); const doc = parser.parseFromString(html, "text/html"); const itemsContainer = document.getElementById("cart-items"); const totalContainer = document.getElementById("cart-total"); if (itemsContainer) { itemsContainer.innerHTML = doc.getElementById("cart-items").innerHTML; } if (totalContainer) { totalContainer.textContent = doc.getElementById("cart-total").textContent; } const itemTotalContainer = document.getElementById(`item-total-${cartItemId}`); console.log('itemTotalContainer:', itemTotalContainer); if (itemTotalContainer) { const quantity = parseInt(itemTotalContainer.dataset.quantity); const newQuantity = quantity + quantityToAdd; const newTotal = newQuantity * price; itemTotalContainer.textContent = `£${newTotal.toFixed(2)}`; itemTotalContainer.dataset.quantity = newQuantity; } }) .catch((error) => { console.error(error); }); updateItemQuantity(); // 购物车更新后,更新页面上的数量值 updateCartQuantity(); // 更新页面上的购物车总数量 }); }
HTML
<div class="cart--box__item" id="item-total-{{item.id}}" data-quantity="{{ item.quantity }}">£{{item.total}}</div>
补充说明:updateCartItem的调用方式
const cartButtons = document.querySelectorAll(".update-cart"); cartButtons.forEach((button) => { button.addEventListener("click", function (event) { event.preventDefault(); const productId = this.dataset.product; const action = this.dataset.action; if (action === "add") { addToCart(productId); } else if (action === "remove") { removeFromCart(productId); } }); }); // 获取用户购物车ID function addToCart(productId, price) { fetch("/get_cart_id/") .then((response) => response.json()) .then((data) => { const cartId = data.cart_id; const csrftoken = getCookie("csrftoken"); fetch(`/api/carts/${cartId}/items/`) .then((response) => response.json()) .then((data) => { let itemExists = false; let cartItemId = null; for (let i = 0; i < data.length; i++) { if (data[i].product.id === parseInt(productId)) { itemExists = true; cartItemId = data[i].id; const newQuantity = data[i].quantity + 1; // 计算新数量:现有数量+1 updateCartItem(cartId, cartItemId, newQuantity, csrftoken, price); // 传入新数量 break; } } if (!itemExists) { createCartItem(cartId, productId, 1, csrftoken); } }); }); }
问题根源与修复方案
问题核心
- 调用
addToCart时未传入price参数:点击按钮触发addToCart(productId)时只传了商品ID,没传价格,导致addToCart里的price参数为undefined,进而传给updateCartItem的price也是undefined,计算newQuantity * price时就会得到NaN。 - 可选兜底:依赖后端数据更可靠:如果不想完全依赖前端传参,可以从后端返回的购物车商品数据中直接取单价。
修复步骤
步骤1:给按钮添加价格数据属性
修改页面中更新购物车的按钮,增加data-price属性传入商品单价:
<!-- 根据你的实际按钮结构调整,示例如下 --> <button class="update-cart" data-product="{{item.product.id}}" data-action="add" data-price="{{item.product.price}}"> + </button>
步骤2:修改点击事件,传入price
调整按钮的点击监听逻辑,获取data-price并传给addToCart:
cartButtons.forEach((button) => { button.addEventListener("click", function (event) { event.preventDefault(); const productId = this.dataset.product; const action = this.dataset.action; // 提取价格并转为数字类型 const price = parseFloat(this.dataset.price); if (action === "add") { addToCart(productId, price); // 传入price参数 } else if (action === "remove") { removeFromCart(productId, price); // 移除操作也建议传入,避免后续逻辑报错 } }); });
步骤3:(可选)从后端响应获取价格兜底
如果担心前端传参不可靠,可以在updateCartItem中直接从后端返回的数据里取单价:
function updateCartItem(cartId, cartItemId, quantityToAdd, csrftoken, price) { console.log('price:', price); fetch(`/api/carts/${cartId}/items/${cartItemId}/`, { // 原有请求代码不变 }) .then((response) => response.json()) .then((data) => { console.log("Cart successfully updated:", data); // 优先用后端返回的商品单价,没有再用传入的price const itemPrice = data.product?.price || price; console.log("CART:", cartId) fetch("/cart/") .then((response) => response.text()) .then((html) => { // 原有DOM更新代码不变 if (itemTotalContainer) { const quantity = parseInt(itemTotalContainer.dataset.quantity); const newQuantity = quantity + quantityToAdd; // 使用itemPrice替代原price计算 const newTotal = newQuantity * itemPrice; itemTotalContainer.textContent = `£${newTotal.toFixed(2)}`; itemTotalContainer.dataset.quantity = newQuantity; } }) // 原有catch代码不变 }); }
额外优化:增加数据校验
计算总价前先校验数据有效性,避免NaN:
const newTotal = Number(newQuantity) * Number(itemPrice); if (!isNaN(newTotal)) { itemTotalContainer.textContent = `£${newTotal.toFixed(2)}`; }
内容的提问来源于stack exchange,提问作者David Henson
相关产品推荐
相关产品推荐

