We're now displaying an "Add to cart" button
on each product page,
but at the moment all it does
is print something to the console.
The final step is to trigger a POST request
to our cart API route.
If we look at the code,
rather than calling the API in the product page
we could do that directly in AddToCartWidget,
so we keep all the cart functionality
nicely encapsulated in this component.
In practice what we want to do
is call "useMutation" here
to prepare the API request
that we then want to send
when the button is clicked.
And we should also be careful
to prevent the user from submitting multiple times,
by hiding the button once it's been clicked,
while the request is in progress,
that is checking the "isLoading" flag.
Once you've done this,
you should be able to go to a product page,
like for the "Golden Pothos",
select a quantity, say 3,
click "Add to cart",
and this should take you to the cart page
showing the "Golden Pothos" product
with 3 as quantity.
So clicking the "Add to cart" button
should not only add the item
but it should also navigate to the Cart page.
Of course you should also be able to add
other products, like "Aloe Vera".
Let's change the quantity to 2 for example,
and add it.
The Cart page now shows
both "Golden Pothos" and "Aloe Vera".
Ok, so this is your final challenge.
Go and implement it.
Let's look at how I have done it.
In the AddToCartWidget component
I'm first getting the "router" instance,
that we'll need to send the user
to the "/cart" page.
Then I'm creating a React Query mutation,
making a POST request for the "/api/cart" route
and passing "productId" and "quantity"
in the request body.
Then, in response to a button click
I'm calling "mutateAsync"
to actually send the API request.
And when it completes I'm calling "router.push"
to navigate to the "/cart" page.
Finally, to avoid duplicate submissions
I'm checking the "mutation.isLoading" flag
and displaying a "Loading" text
instead of the button
while the request is in progress.
And that's it.
I kept all the mutation code in here
for this example,
but ideally you could move it to a separate
custom React hook.
Either way, this was the last challenge
so congratulations if you made it this far!