Now, what do we need to do here
when it comes to updating the dom?
Well, of course, in the cart item,
we want to update the total price of the product here
because that changes with the quantity.
And on the overall cart, we want to update the total price
that's shown at the bottom.
In the navigation bar we also want to update this badge,
of course.
Now to update the total price for a single product,
conveniently, I'll wrap this price into a span so that I can
select this span in my JavaScript code,
and then change the text content off it with JavaScript.
And I'll give this a class of cart item total,
or a cart item price, whatever you want.
So that we can use this to identify the span,
which we want to update with the updated price.
If we have a look at the cart controller.
For update cart item,
we see that we return the updated cart data property,
which holds a nested object with the new total quantity,
the new you total the price, and the updated item price.
So these are all the data pieces that we need
for updating the dom.
Hence, here in cart item management,
we now need to get access to the different pieces
that you want to update.
And that, for example,
starts with the cart item total price.
Here, I'll select the element
for this cart item total price.
And that of course is this span, which I added a second ago.
To get access to this span,
we can have a look at cart item EJS again.
And we see that it's this span, in this cart item,
which belongs to this form.
So what we could do is, since we got access to this form,
in our front-end JavaScript code,
we could go to the parent element of this form,
which has this article, and then there search for the item
with this cart item price class.
This would give us access to this span.
And whilst it is only one possible way of doing this,
it is the way I will choose here.
So here, I will get access to this element by using my form
and then the parent element of that form,
which is the article.
And then there we can call query selector.
We can not just call this on the overall document,
but on any dom element to search deeper
into that dom element.
And here I'm calling it on the article dom element to
which our form belongs,
to then find the first matching item
with the cart item price, CSS class.
And that should then be the item which I want to update.
So I'll update this cart item total price element,
and set its text content equal to response data.
And then there, if we have a look at cart controller,
it's the updated item price I'm interested in.
So I'll set this equal here,
and I will also call to fixed two here,
to make sure that we always set this to two decimal places.
Now we also need to update the cart total.
So, the cart total price element is
another element we're interested in.
And we can get access to that
if we have a look at cart EJS by simply looking
for the id cart total on the page,
and then the first element child in there is our paragraph,
where we want to set a new price.
So we can look for cart total.
And we can also wrap this into a span here,
so that we can easily select just the price.
By giving this span an id of cart - total price,
for example.
So, that's now my total price and we can select this id,
of course, in our cart item management JS file.
In there, I can use document get element by id
and select the cart total price id element,
which is that span that wraps the cart total price.
And we then just set
cart total price element.text content equal to.
And then again if we have a look at the card controller,
it's this new total price,
which is that new cart total price I'm interested in.
So that's what I access on my response data like this.
And again, I call to fixed two here
to force two decimal places.
Last, but not least,
I want to update the badge here in the navigation area.
And for this, we can get the card badge again
by using document query selector, nav items.
So this clause, and then the badge in there.
In case you're not sure about this,
you can again have a look at the header,
I mean, at the nav items
and there you find that we have the class nav items
on the unordered list and in there this span with
the class badge, which is our cart badge.
So with that, we select this item here once we need it.
And then I said, cart badge.text content equal
to response data.
And if we have a look at the cart controller,
that's not a new total quantity we're interested in here.
So that's the value we want to set here.
Now, unlike earlier,
here I'm just selecting the items when I need them,
instead of selecting them right at the beginning
of the script file, either way works.
Here I'm just doing it just in time,
because some these elements, specifically this element,
depends on the exact form for which the event was caused.
The other elements,
which exist only once on the page anyways,
could have been selected before
at the beginning of this page. This would have been fine.
Either approach works.
The difference simply is that if this runs more often,
if it's inside the function, as it's currently,
we run this code and search
for this element every time the function executes.
If it's at the beginning of the file,
we only do this once when the file loads.
And therefor,
I will actually move these general selectors,
for the cart total price element,
and for the cart badge up to the beginning of the file,
so that we only run this once at most and not unnecessarily
every time we update our item.
But it wouldn't be horrible if you do it the other way.
With that, however, we added a bunch of logic.
Let's see whether this now works.
For this, I'll also open a console
to see potential error messages.
And then here, I want to change this first cart item
to a quantity of two.
If I click update I get an error.
And I get an error here because product is not defined
inside of the update item method.
So let's have a look at the cart model,
which is where we have this method. And there,
the problem is that I'm somewhere accessing product
where I don't have a product, as it seems,
in line 40 in the cart model EJS file.
Just JavaScript, not EJS.
Yeah. Here, product price. That of course is wrong.
It should be item.product.price.
The same as true down here in line 44.
Okay, if we save this and reload.
If I now set this to two, now I get an error,
cannot read property to fixed of undefined.
If I reload, however, we see it worked.
It just wasn't updated in the dom correctly.
Now let's see why that failed.
And for this, I'll go
to my cart item management front-end JavaScript code,
where one of these two fixed calls failed.
And here I want to console log the response data to see
if there is something wrong with the response data,
or something that would explain that error.
If I reload now and I changed this to free again,
this is my response data here,
and we see the updated cart data with the new quantity.
Oh yeah. Because updated item price
and new total price are not directly in the response data.
Neither is new total quantity.
They are nested in the updated cart data,
property and object, here.
So, we should access response data.updated cart data
in all three places so that we dive into this nested object
and we extract the updated data there.
With that, if I reload and set this to two now,
this now looks better.
This updates, this updated, and the total price updated.
And if I set this to zero now, then it's kind of removed
but only really if I reload.
Of course, we also need to add logic for this case,
that we really remove item by setting the quantity
to zero or a negative number.
For this, back here in cart item management,
instead of console logging the response data,
I actually want to check if response data,
updated cart data, updated item price is equal to zero.
Which of course means that the item was removed entirely,
because we have a price of zero for this item now.
You can see this, if I update this to zero,
in the response data we have updated item price
of zero in this case.
In that case, I want to get the parent element of my form,
which is this article that wraps the form
and get the parent element of that,
which is to list item that wraps the article,
so now I'm talking about this list item,
which wraps to single cart item.
I get access to that by using parent element twice.
And I simply want to remove that now.
Therefor we also only want to update the price
for the item if it's still there
and that will then happen in this else block therefore.
If we removed it, this would fail
and updating what fail most importantly.
So therefor, I moved these two steps into the else block
so that we only performed them
if the cart item is still there.
Otherwise we remove it and we then just continue
by updating the cart total and the new total quantity.
With that, if we go back
and we start adding more products to the cart.
Here we are. If I now update this, this works,
but if I set this to zero, this now was removed.
And now with that, we can now update the cart correctly.
We can add items to the cart, as many as we want.
And of course, then as soon as we did add items to the cart,
we can also manage to cart here.
And add more cart items by increasing the number of here,
or of course remove items if you want to,
or just reduce the amount of items. That is all possible.
And that's the finished cart logic for now.
Now I want to make sure that this buy products button is
only visible if we can buy products.
So if we are logged in,
because whilst a cart should be accessible to all visitors,
buying products and checking out the cart
should only be possible for logged in visitors.
And then once we did buy the products,
I, of course, want to have an orders page
where we can view all the past orders
and their current status.
And then the administration area.
We want an area where we can administrate these orders,
where we can see them and change their status.