sajjad566's avatar

Update other component from one component

Hi, I am developing an eCommerce store with vue and laravel. I am showing the cart component inside the home component. But whenever I add an item to cart that in real time is added to the cart but the cart coomonent does not update.

Cart.Vue Code:

<template>
	<div class="cart">
		<a href="#" class="lavender-btn shadow-sm" @click="openNav">&#9776; Cart {{ cartItems.length }}</a>
		<div id="mySidenav" class="sidenav">
		  <a href="javascript:void(0)" class="closebtn" @click="closeNav">&times;</a>
		  
		  <div class="cart-item m-2 p-2 shadow-sm" v-for="(item,index) in cartItems">
		  	<div class="row">
		  		<div class="col-3 text-center">
		  			<img v-bind:src="item.attributes.image" class="w-100 img-thumbnail" alt="">
		  		</div>
		  		<div class="col-9">
		  			<div class="row">
		  				<div class="col-10">
		  					<b>{{ item.name }}</b> ({{ item.quantity }})<br>
		  					<small>{{ item.attributes.category }}</small><br>
		  				</div>
		  				<div class="col-2">
		  					<div class="text-danger font-weight-bold removeProduct">x</div>
		  				</div>
		  			</div>
		  		</div>
		  	</div>
		  </div>

		</div>
	</div>
</template>

<script>
	export default {
		name: "Cart",
		data() {
			return {
				cartItems: ""
			}
		},
		mounted() {
			this.getTheCart();
		},
		methods: {
			getTheCart() {
				axios.get('/getTheCart')
				.then((response) => {
					this.cartItems = response.data;
				})
				.catch(err => console.log(err));
			},
			openNav() {
			  document.getElementById("mySidenav").style.width = "350px";
			},
			closeNav() {
			  document.getElementById("mySidenav").style.width = "0";
			}
		}
	}
</script>

Home Vue:

<template>
    <div class="container-fluid">
        <div class="theLoader" v-if="loading">
            <div class="spinner-border text-dark" role="status"v-if="loading">
              <span class="sr-only">Loading...</span>
            </div>
        </div>
        <div class="container all-categories mb-5">
            <div class="row">
                <div class="col-6">
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle shadow-sm" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                          Categories
                        </a>
                        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                            <router-link to="/" class="dropdown-item">All Categories</router-link>
                            <router-link 
                              :to="{ 
                                name: 'Category', 
                                params: { 
                                    cname: category.slug 
                                }
                              }"
                               class="dropdown-item" 
                               v-for="category in allCategories" 
                               v-bind:key="category.id"
                               @click.native="getProducts">
                                {{ category.name }}
                            </router-link>
                        </div>
                      </li>
                </div>
                <div class="col-6 text-right">
                    <Cart v-bind:is="Category" />
                </div>
            </div>
        </div>
        <h1 class="text-capitalize">{{ this.$route.params.cname.replace('-', ' ') }}</h1>
        <div class="groceries">
            <div class="row">
                <div class="col-sm-2" v-for="(product,index) in allProducts">
                    <div class="single-product text-center">
                        <img v-bind:src="product.image" width="200"/>
                        <h3>{{ product.name }}</h3>
                        <input type="number" min="1" v-model="qty[index]">
                        <button @click="addToCart(product.id, qty[index])">Add to cart</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
  
<script>
    import Cart from './Cart.vue';
    export default {
        name: "Category",
        data: function() {
            return { 
                allProducts: "",
                allCategories: "",
                loading: "",
                qty: [],
                cartElements: [],
            }
        },
        components: {
            Cart
        },
        mounted() {
            this.getProducts();
            this.getallCategories();
            console.log('Component mounted.');
        },
        methods: {
            getallCategories() {
                this.loading = true;
                axios.get('/categories')
                .then((response) => {
                    this.allCategories = response.data;
                    this.currentTitle = "All Products";
                })
                .catch(err => console.log(err));
            },
            addToCart(product_id, quantity){
                axios.post('/cart/add/'+product_id+'/'+quantity)
                .then((response) => {
                    alert(response.data);
                })
                .catch(err => console.log(err));
            },
            getProducts() {
                this.loading = true;
                axios.get('/grocery/'+ this.$route.params.cname)
                .then((response) => {
                    this.allProducts = response.data;
                    this.loading = false;
                })
                .catch(err => console.log(err));
            }
        }
    }
</script>
0 likes
2 replies
ajohnson6494's avatar

It looks like your cart component is not getting updated when and item is added to the cart. I can think of two options for you.

  1. (simplest) Pass the cart items into the cart component as a prop.
  2. (more complex, but also more flexable) Setup Vuex to use a store that would house your cart data. Then anytime you add to the cart any component that would need that data would be updated. Vuex Docs
sajjad566's avatar

@ajohnson6494 Thanks. But I found another way using :key attribute. any update ok key automatically refreshes the cart component

Please or to participate in this conversation.