Home > Back-end >  Vue.js - Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'product
Vue.js - Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'product

Time:05-26

I'm currently working on an eCommerce app using Django and Vue.js and I am currently trying to find out why my CartItem.vue component is not working. Its suppose to display the product, product price, the number of products selected, and the total price of the number of products selected.

<template>
  <tr>
    <td>
      <router-link :to="item.product.get_absolute_url">{{ item.product.name }}</router-link>
    </td>
    <td>₱{{ item.product.price }}</td>
    <td>{{ item.quantity }}</td>
    <td>₱{{ getItemTotal(item).toFixed(2) }}</td>
    <td><button ></button></td>
  </tr>
</template>

<script>
export default {
  name: 'CartItem',
  props: {
    initialItem: Object
  },
  data() {
    return {
      item: this.initialItem
    }
  },
  methods: {
    getItemTotal(item) {
      return item.quantity * item.product.price
    },
  },
}
</script>

But whenever I execute my code I get this error:

CartItem.vue?5193:4
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'product')

I have tried and have used the .product method multiples time and this is the first time the compiler can't read it.

If you are wondering, this is the main cart link code:

<template>
  <div >
    <div >
      <div >
        <h1 >Cart</h1>
      </div>

      <div >
        <table  v-if="cartTotalLength">
          <thead>
            <tr>
              <th>Product</th>
              <th>Price</th>
              <th>Quantity</th>
              <th>Total</th>
              <th></th>
            </tr>
          </thead>

          <tbody>
            <CartItem v-for="item in cart.items" v-bind:key="item.product.id" v-bind:Item="item" />
          </tbody>
        </table>

        <p v-else>You dont have any product in your cart...</p>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import CartItem from '@/components/CartItem.vue'

export default {
  name: 'Cart',
  components: {
    CartItem
  },
  data() {
    return {
      cart: {
        items: []
      }
    }
  },
  mounted() {
    this.cart = this.$store.state.cart
  },
  computed: {
    cartTotalLength() {
      return this.cart.items.reduce((acc, curVal) => {
        return acc  = curVal.quantity
      }, 0)
    }
  }
}
</script>

CodePudding user response:

Your CartItem prop is called initialItem but you are setting Item in the main cart link code. Updating <CartItem ... v-bind:Item="item" /> to <CartItem ... v-bind:initialItem="item" /> should fix it.

For this to be raised in a clearer manner, you should update your prop declaration to make InitialItem required:

  props: {
    initialItem: Object,
    required: true,
  },

CodePudding user response:

you are trying to access an optional prop which is probably fetched from the server.. this means it takes some time to load so it is initial value is null or undefined depends on the context..

so some solutions : you may do this:

<span v-if="item.product && item.product.get_absolute_url">
  <router-link :to="item.product.get_absolute_url">{{ item.product.name }} 
  </router-link>
</span>

also you would wanna change for the produce in every other place you are using it ..


i would also recommend you to define your props like this :

  props: {
    initialItem: {
      type:Object,
      required:true
    }
  },
<template>
   <div v-if="initialItem">
     {initialItem.product }
   </div>
</template>

let me know if the problem is not solved

  • Related