You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

前端更新购物车项总价返回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);
          }
        });
    });
}

问题根源与修复方案

问题核心

  1. 调用addToCart时未传入price参数:点击按钮触发addToCart(productId)时只传了商品ID,没传价格,导致addToCart里的price参数为undefined,进而传给updateCartItem的price也是undefined,计算newQuantity * price时就会得到NaN。
  2. 可选兜底:依赖后端数据更可靠:如果不想完全依赖前端传参,可以从后端返回的购物车商品数据中直接取单价。

修复步骤

步骤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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:24:57