For the delete button, let's again start with the Redux logic.
So here in the actions for example, we can register a new identifier, remove from cart sounds like a fitting
name given that we had add to cart before, so remove from cart.
I'll also again add an action creator function here, remove from cart.
This now only needs the ID of the product that should be removed,
so only product ID and then this returns a new action object where the type of course is remove from
cart and where we have the pid, the product ID, where I forward the product ID I'm getting here. Now
in the reducer, we had that add to cart
case, now we simply need to add another case here
and that case is the remove from cart case.
For that, you need to make sure you're importing the removed from cart action identifier from the cart
actions file
and in the remove from cart
case here, we have two cases again.
One is that we only had one item of that product in the cart,
like for the blue carpet,
in this case we need to remove it entirely from the cart
items object,
so from this object and this will therefore then remove it from this row which we output here.
If we have two or more items, then we just want to reduce the quantity by 1.
Of course you could always erase this item entirely if you wanted to but I want to show you how you
could differentiate between these two cases.
So actually if we have a quantity higher than one, I don't want to erase the item from the cart but actually
just reduce the amount by 1.
So therefore in remove from cart, we have to find out what our quantity is. So our current quantity which
I store in this constant can be deducted from our state of course, there in the items, we have to find
the product we're looking for
and of course we can do that with the help of the ID which is part of our action here in the pid field
because now state items is an object and therefore we can access action.pid here, right.
This will dynamically access the value with the product ID
key here in our item,
so with the product ID we're getting on this action and
this is how we add items to our items object here right.
We use our product ID as an identifier,
this is now what I use here to get access to it.
This will have a quantity because this will hold a value which is a product item,
you could of course also add a check whether this item is actually part of the cart
but the way we build this app, we should never be able to reach this action without that product being
part of the cart because we can only trigger our delete action here from inside the cart screen, so we
don't need to check here but we definitely need to get the quantity.
Now we can check if current quantity is greater than 1 which means we need to reduce it, we need to reduce
it, not erase it, else
we need to erase it.
Now let's start with the erase case.
So here we just need to return a new items object which includes all the old items but doesn't include
this item anymore. So we can have our updated cart items here where we clone state items, like this and
now to remove a property, we can use the delete keyword Javascript knows and there, we can delete updated
cart items for action.pid.
So this will delete this item from our copied Javascript object here, it will delete this item entirely,
this product item entirely from our cart items object. This is how we can erase it. Now in the other case
that we simply need to reduce it,
I can have my updated cart item, so that single cart item where I create a new cart item with the cart
item class and there, I want to copy the values of the existing cart item but simply reduce the quantity.
So cart item takes quantity right as the first values, so now here
the goal is to get access to state items for the product ID I get on the action and since repeating this
will be cumbersome, I'll store it in a helper a constant, selected cart item is this here,
now we can replace that here with selected cart item
and here I can use selected cartItem.quantity minus one.
Now of course we know that this won't be zero because the quantity was greater than 1 and now we can
keep the rest of the data of course.
So we keep the product price here, we keep the product title,
that all doesn't change, the sum however of course changes and
that's the sum, the old sum minus the price of course,
so minus the product price because we removed one item, we have to reduce the sum by one item's price.
Now this updated cart item needs to replace the current item in our cart items object. So that
we can also reuse some code, I'll actually change this a little bit and create updated cart items as a
variable here instead of a constant here in the else block, so that I just update this variables value,
so that here in the if block,
we can also use that same variable name, updated cart items where I set this equal to a copy of the existing
items but then I replace my action pid here, so my product ID, my identifier, the value there with the
updated cart item which is my old cart item with the updated quantity and sum. That's the updated cart
items,
now of course we will also need to adjust the total amount of our state, so after this
if else block, we return a copy of the state, items can be set to updated cart items and now important,
the total amount can be set to state
total amount minus selected cart item
product price because just as I updated the sum for this single cart item, the total cart sum of course
also needs to be readjust as such. Now we can try dispatching this remove from cart action.
So let's go to the cart screen where I in the end have this on remove function and there, I now want to
dispatch an action, so I will need access to the dispatch function with the help of the use dispatch
hook. We can now use that up here, get access to it by calling just use dispatch like this and then
dispatch this down there.
Dispatch now import all actions which we need, so import everything as cart actions from the store folder,
from actions cart like this, again using this bundled import which is totally optional, you can also target
the specific things you need,
so target the specific action creators, in this case the remove from cart creator which we would need
and then down there, simply execute this action creator,
in my case by using cart actions.removeFromCart, forward the product ID which we of course get
here, it's itemData.item.
and now keep in mind that we're looping through items of this shape, so we'll have a product ID field in
there and hence we can use this here to forward this to remove from cart,
this should hopefully therefore allow us to update this. And that should be all, Redux should do the
rest behind the scenes and should automatically rerender the cart screen whenever the cart changes,
so whenever we remove items. So I added two red shirts and one blue carpet and if I remove one red shirt,
indeed
well one problem we have is the order switches, we'll have to fix that
but you see the quantity was updated correctly.
If I now remove this, the total amount also updated correctly, if I now remove this, indeed it's gone entirely
and now this also is disabled.
So this generally works but of course the order being switched,
that's not something I want to happen here.
Now to avoid that the order switches, we can simply go to the cart screen where I change my items to
be an array and there, we just need to make sure this array is always sorted in the same way because
this selector will always re-trigger and refetch our data whenever our Redux state changes.
So therefore here, we will always get the latest data snapshot we have in there and hence, it's in here
where we just need to sort it in the same way all the time and will therefore always render it in the
same way.
So we just need to make sure that our transformed cart items array is sorted by calling sort there.
If I call it like this, I start adding some data here,
now you see this alone didn't do the trick because we're not telling it how to sort it and it doesn't
know how to do this for objects out of the box but we can pass a function to sort where we always compare
two items, a and b, to each other and then sort has to return a number
in the end that determines what comes first
and there, you can of course sort this however you want,
for example by product ID, so we can simply return a comparison where we check A's product ID, compare
this to B's product ID and if it's greater, then with a ternary expression here, I returned one,
otherwise I return minus one.
This is the normal sort function Javascript ships with and now this ensures that we always sort in
the same way,
hence now you see if I remove this, the red short stays in its place and therefore our cart logic is finished.
Now we can make sure that we can actually also click on that order now button and we add this as an
order which we thereafter can visit with the helpful drawer here that allows us to go to the orders screen
which we of course also have yet to add.