The last part that we need is to get the buttons to work.
So we can add elements to the order and then we can render the order.
Make sense?
So, we have a button here, so I wanna click here and
I wanna add something to the order.
So, let's do that.
For that, we're going to create our final service,
it's going to be called Order.js.
In this case, we're going to start with a function.
Add to cart, it's going to receive an id and
it's going to add that element to the cart, okay?
So first, we receive an id, we need the product.
So we're going to call getProductById that we have already created a few minutes ago.
And that was, I'm not sure if you remember,
an async function, so I need to await for it.
After that, I need to check if I already have that element in the cart.
So if I'm adding a cappuccino,
if it's the first cappuccino in the cart, I need to add a new entry.
If I already have a cappuccino, I need to update the current entry from one to two
cappuccinos, does it make sense?
So I need to find from app.store.cart.filter,
let's call this prodInCart,
swade it in a new line.
I'm going to check if the the product.id it's
equal to the current id, something like that.
So, This is filtering,
it's creating a new array, filtering the results.
So we're going to check, it's a simple way, I can use also indexOf.
But because it's a deep object, it's a little bit more complicated.
So I will check if I do have 1, it means that that product is already in the cart.
Make sense?
In that case, I need to update, okay?
So I need to update the current item.
If not, it's a new one, so
I need to take my cart and let me start with this.
I'm going to push, if this is wrong, and I will explain why in a minute.
So I need to push a new object that will contain the product that I wanna add and
the property quantity as 1 because it's
the first cappuccino that I'm adding to the cart.
Why is this wrong?
It's not wrong, but
it's wrong in how we set up the proxy.
And that's the tip, proxy, why is wrong?
If we are pushing something new to the array, are we changing the cart?
Let's go back to the store.
We have a proxy.
In the proxy, we check if the property cart has changed,
but how we actually change the current property?
The cart this is still the same cart,
we're changing the contents of the cart but not the property itself.
Does it make sense?
So, because of that, and by the way if you're using Redux or
other state management solutions, they typically have the same problem,
and that's why you know we need to return a new array, not change the array.
Does it make sense?
You can change this and make it differently,
I'm not saying this is the only way.
Because of that, now I don't wanna push here this.
I'm going to create a new array that will contain,
will spread the current cart and it will add that new option.
So in this case, I'm assigning a new array to the cart, so I'm changing the array.
Does it make sense?
Again, this is because how we set up this.
You can also set up this in a different way.
Updating the current item is a little bit more weird when you see that.
So we also need to create a new cart.
So one quick way to do that Is to use map and then try to find,
If the current id is the one that we are adding, and if that's the case,
we can do something like this, so this is a ternary operator.
If it's this, we're going to return a new object with all the properties and
quantity being the current quantity plus 1.
It looks a little weird, but if not,
we are just returning the product as it is.
That's how you return a new array with one element changed.
This has nothing to do with Vanilla JS it's just how we are dealing with data,
data management, data structures in JavaScript.
Again, you can use the data library if you want to make this simpler.
So, now that we have this, we can also add, this is add to cart just
because we are here and we know that we may need that, let's use remove from cart.
And, again, we are not going to remove one element from the cart,
we're going to create a new cart to trigger the update mechanism that we have.
And it's going to be a filter.
So we are going to check, If the id,
Product id is not the one that you wanna remove.
So we are creating a new array, removing the one with that id.
Make sense?
We are filtering the array.
So now that we have the add to cart method up and running, we should call it.
We have two places, we have the menu and also we have the details, okay?
So we should call that on both places.
So we have the details page that has to do here.
We just need to, Remove the comment.
And by the way, add to cart needs to be importer because it's a function,
That we need to import from Order.js.
We are using ES modules, nothing is global here, so we need to import everything.
And we can import everything because we are exporting these functions,
so they can be used from the outside, okay?
So that's the detail page, and then we have menu page.
Menu page, Is adding, remember, product items.
So we need to, product item, if you remember,
was another web component that has a TODO here.
So what's the TODO?
We need to add to the cart and
the id is actually product.id, okay?
How do we know if this is working without finishing
the last section that is the order page?
There is something interesting that I have already set up in the HTML and
you didn't know.
We have this little icon here, and there is a little span
here going on in red color that looks like an iOS badge.
So, we can actually, every time the cart is changing,
we can change that even before rendering the section.
And to do that, we can do that in app.js because this is like global,
it's part of the navigation.
So I'm going to add another EventListener for the window, but not for
a DOM content loader, is going to be app.cart.change.
That's my event, my custom event.
So every time the cart is changing, I want the app to do something.
So this is kind of reacting to data changes.
Is one way to do reactive programming in manage.js,
not the only way, maybe not the best way, one way.
And here we are going to update the badge.
The badge is just an element, so
we are going to take ElementById, take the badge.
And we just need to take the current amount of objects that we have in
the cart.
But the quantity, it's not just app.store.cart.length.
Why?
Because that will give me how many different items we have in the cart.
But maybe we have 10 cappuccinos, so I wanna see 10.
So, the simplest way to do that in functional programming is to use reduce,
okay?
It's not complicated, but we have an accumulator and each item and
we're going to say, this is just simple programming,
that we are accumulating from every item the quantity
starting with zero, something like that.
That's our accumulator.
So I'm going to take the textContent and set this as quantity like that.
And also, I want to change the hidden property and
say there's going to be equals to quantity 0.
Because if I don't have any elements in the cart,
if it's empty, I don't wanna see 0 in the cart, okay?
You will see that in action in a minute.
So this is how we can use DOM events to listen for,
in this case, data changes and react in consequence,
some kind of global context events.
Okay, so I'm trying this and I'm getting errors, that's because of VS Code.
VS Code, as I mentioned, it's not adding .js when it's adding imports and
that works with Webpack or TypeScript, but not here.
The other one that I have is product item.js,
I need to add the.js and here we are again.
So the idea is that if I click add, automatically,
look at the top right, I have a 1.
And if I continue adding elements, it actually works.
So remember what's going on here.
So add is calling add to cart.
Add to cart is creating a new array with the new cart and
that because we have a proxy, that proxy detects the change and
it's broadcasting a DOM event over the window that then we can listen
in a lot of places in our app and mixing several techniques at the same time, okay?
But it works.