Array push replace old data by new one

I’m creating a cart system in my app with vuejs I have a list of products, I loop those by v-for directive this fine, but the problem is when I want to add a product in a cart it added and I checked there id have or not if id exist then I update the quantity else push, but the main problem is that when I want to push new product in my cart the new show only and the old one is hidden from the array,

you can see my gif image here it shows only the last one which means that whatever product I want to add only shows that one, other not, I searched a lot and found many solutions but nothing works for me, my bad luck.

Shop.vue

here I loop my products and pass the product prop in my ProductCard.vue

<div class="product-cards row">
  <ProductCard
     v-for="product in products" :key="product.id"

    :product="product"
    class="col-sm-6 col-lg-4"
  />
</div>

In my

ProductCard.vue

<template>
  <button
    type="button"
    class="product__btn add_to_cart_btn"
   
    @click.prevent="addToCart(product)"

    :disabled="addCartLoading"
  >
    Add to cart
  </button>
</template>

<script>
import { EventBus } from "../app";

export default {
    name: "ProductCard",

    props: {
        product: {
            type: Object,
            required: true
        }
    },

    data() {
        return {
            addCartLoading: false,
            shoppingCart: [],
            quantity: 1
        }
    },

    methods: {
        addToCart(product) {
            let found = this.shoppingCart.find(cart => cart.id === product.id)

            if (found !== undefined && found !== null) {

                found.qty = ++this.quantity

            } else {
                this.shoppingCart.push({
                    id: product.id,
                    name: product.name,
                    qty: 1,
                    price: product.price,
                    options: {
                        old_price: product.old_price,
                        image: product.image,
                    }
                })
            }
           
            EventBus.$emit('cartContents', this.shoppingCart)
        },
    }
}
</script>

when I console.log(this.shoppingCart) it looks like this, if add new then it should looks like

[
 0:
  id: 11,
  image: url,
  .......,

 1:
  id: 12,
  image: url,
  ....
]

but not, when I add new it shows like below the image

console image

Answer

Your problem exists because you are having one shopping cart with each ProductCard component.

In pseudocode what you are doing is:

1. render each ProductCard
2. click on the "add cart" button
3. add the product to the cart of this specific `ProductCard` component
4. use the event bus to emit this new shopping cart (therefore replacing the old one)

You should reconsider your code to only emit the product that was added. Your application only has one shopping cart. It doesn’t have n shopping carts, therefore you only need one instance of the shopping cart.

A solution to your problem (please, feel free to change it to your needs) could be something like this:

ProductCard

<template>...</template>
<script>
export default {
  ...,
  methods: {
    addToCart(product) {
            EventBus.$emit('cartContents', product)
        }
  }
}
</script>

Then we would handle this emit event by following this simple pseudo-code:

1. receive event
2. check if this product is already in the cart
3. if it is in cart increment its quantity
4. if it's not in the cart insert a new product in the cart with quantity 1

Translating to Javascript something like this:

const products = [];

// 1. receive event
const onProductAdded = (product) => {
  // 2. check if this product is already in cart
  const product = products.find(p => p.id === product.id);

  // 4. if its not in cart insert new product in cart with quantity 1
  if (!product) {
    //  the same as doing `products.unshift({ id: product.id, quantity: 1, "and so on to all other properties" })`
    products = [{...product, quantity: 1}, ...products];
    
    return;
  }

  // 3. if it is in cart increment its quantity
  const selectedProductIndex = products.findIndex(p => p.id === product.id);
  products[selectedProductIndex] = {...products[selectedProductIndex], quantity: products[selectedProductIndex].quantity + 1};
}