You've done some amazing work getting to this point! You've created your own Product component and we're now rendering products on the page dynamically. You also know what methods and computed properties are and how they work. Now it's time to take a look at events and specifically, how we can emit an event to add a product to the cart.
You'll notice that we've got the 'Full details' and the 'Add to cart' buttons, but neither of them work because we haven't wired them up. Let's rectify that and wire up the Add to cart button so it adds the Product IDs to the cart.
In your Product component, modify the button as follows:
<button v-on:click="addToCart(product)">Add to cart</button>
The v-on
tells Vue to add an event listener to the button and to run the addToCart
method on click. If you're familiar with JavaScript events, you'll appreciate that this is a nice efficiency gain as you no longer need to write and manage events yourself.
Add a new method to the methods object in the Product component to handle the click:
// Product component
addToCart(product) {
console.log(product);
}
Refresh your page and click one of the Add to cart buttons. You should see the product logged to the console.
Now we have a problem to solve. We need to push the product's ID into the cart array, but the cart exists in the data object that belongs to the app component. For security and data integrity reasons, we can't directly access it via the Product component. There are a number of ways to solve this and two examples are:
Emit
an event up to the app component and pass up the ID to a method that can add the Product ID to the cart
Use a centralised state management tool like Vuex
Using Vuex at this point is a little overkill as there are only two components. For that reason, let's emit an event and solve the problem that way. We'll incorporate Vuex later when our app becomes more complex
Let's visualise the process in a diagram:
In your index.html
file, add a v-on
line to your Product component render tag to register the 'add-to-cart' event with the Product component.
<product
v-for="product in this.products"
v-bind:key="product.productId"
v-bind:product="product"
v-on:add-to-cart="updateCart" // Register the 'add-to-cart' event
></product>
Head back to your addToCart
function in the Product component and add:
// Product component
addToCart(product) {
product.addedToCart = !product.addedToCart;
this.$emit('add-to-cart', product.productId);
}
Firstly we've change the addedToCart
property on the product to be equal to the opposite of what it currently is. For example, if addedToCart
is false, !product.addedToCart
will return true because a false becomes true when used with the NOT operator.
In a similar fashion, if addedToCart
is true, then !product.addedToCart
will return false because the NOT operator will only return true if the variable is 'falsy' (ask your coach if this concept is confusing).
Next up, we emit the event back up to the app component using the event add-to-cart
. The app component receives this signal, and fires the updateCart
method, which receives the Product ID.
Now in your app component, add the following method into the methods object:
// app component
updateCart(productId) {
this.cart.push(productId);
console.log(this.cart);
},
Notice here we simply push the ID into the cart, then log the cart array (you can remove the console log later). If all has gone well you should see the Product ID added to the cart and the cart value in the header incrementing.
We can now get our button to react to the changes by adding the following ternary operator:
<button v-on:click="addToCart(product)">
{{ product.addedToCart ? "Remove from cart" : "Add to cart" }}
</button>
The problem we have now is that you can continue to click the button and the ID will get added to the cart array over and over again.
Modify the updateCart
method in your app component so that it checks whether the ID already exists in the cart array
If it doesn't exist, push the ID into the array and return
If it does exist, use a method to find the array item and remove it