Pressing the detail button here in the order items should expose all items we have and for this, I want
to use the cart item here.
One way of doing this is to handle some internal state here with the help of the use state hook which
we import from React where we control whether we're currently viewing the details or not. So I'll name this
show details and set show details here
and initialize this with use state to be false so that we don't show the details initially
and now when we press this button here, I of course want to change this state. So there in this function,
I will call set show details and basically invert the value, for this we use the special syntax where
we pass a function to that state setting function here, where we get the previous state and we then return
a new state based on that previous state
and here, keep in mind that previous state is indeed false or true depending on what show details was,
so here I will return not previous state to convert this, if it was false, I will return true as a new
state, if it was true, I'll return false as a new state and I'll set this to show details.
Now we can use that information here to output some content conditionally. We can check show details
and if that is true and this is now our React syntax we can use here,
so if this is true, then we return this view here. Might look strange at first but with that we're saying
if this is true and this is true and this is a shortcut for Javascript to check if this is true,
well this is always true-ish because this is an object in the end so this will then be rendered,
that's how Javascript works.
The alternative would be a ternary expression or a variable which you set up here which you change
with an if check and then output down there.
So I'll use this inline expression here where I output this view if show details is true
and in this view, I want to output all the items.
So in this view, I'll have a dynamic output where I go through all my items which I expect to get on the
items prop of this order item component
and there, we can map our data into a list of jsx elements, into a list of components.
So here, I of course get my cart item in the end because items in an order are just the items we had in
the cart, so map executes this function on every cart item so to say and gives us that cart item it's
currently looking and now for this item, we have to return a new jsx element we want to output and
that's where I use my cart item to output that.
So here, I output cart item like, not cart but cart item like this. Now the cart item if you have a look
took the quantity and the title as inputs and it also wanted the amount.
In addition, we had the delete button there which I don't want on the order item, so we have to do something
about that
but let's focus on quantity, title and amount for the moment and pass in these data pieces.
So here, quantity is cartItem.quantity, amount is cartItem.
and now remember that whatever we store here in orders, in items is in the end what we get as items here
in our orders reducer,
so what we get in our action. So we get our cart items there and if we have a look at the cart screen
and have a look at what we pass in there, then for add order, we pass in this cart items constant which
holds this array we generate here in the end.
So in the end, we have an array of such objects in there,
so we have the product title, the product price, the quantity and the sum in there and that's what we can
now work with here in order item where I create my cart items, I pass in the cartItem.quantity, for
the amount, I pass in cartItem.sum and last but not least in the cart item,
we also need the title, so that will be cartItem.productTitle what I pass in here.
Now the remaining problem as I said is that a cart item has this touchable
icon here to delete it, this only make sense if we use this component inside of a cart,
not when we use it inside of an order we want to output which is of course read-only.
So the solution is that here in cart item, we wrap this and simply expect to get a prop that says for
example deletable and only if that's true,
same shortcut as a second ago, we output this touchable opacity,
so this icon in general,
otherwise we don't.
So now we have this deletable prop in the cart item which needs to be set to show that trash icon.
This means that in the cart screen where we want to have that trash icon, when we use the cart item there,
we do need to set deletable and setting it like this suffices,
this sets it to true and we'll show it. On the other hand, in our order item
where I also use the cart item, there I don't set deletable and therefore we'll not render this trash
icon. So let's have a look at this,
let's save it and let's add these items to the cart,
press order now and then go to the orders, click show details and I get an error, props
items map can't be called because undefined is not an object.
A reason for that is that I'm trying to loop through all my items here on the order item but in the orders
screen, I'm never setting the items prop here.
So in the orders screen for the order item, besides passing in the amount and date, we also need to pass
in the items for that order item we're outputting and that of course can be received or can be gotten from
our itemData.item which is a single order
and now if we have a look at the order model, in there we'll have this items property here. So we can
access .items here
and now we pass the items into the order item and therefore now we can also output it there.
So now if you give this another try and we place a new order here and we simply have a look at this,
now this works, we got a problem with the key here which we'll fix in a second.
Let's first of all also try this on Android, click order now,
then go to orders, show the details, get the same warning but I've written that it generally works, though
it would be nice if these order items were a bit broader so that's also something I want to fix. So to
fix these errors
we have, the warning stems from the fact that here I'm mapping my data into React components and if we
do this manually with map here, we need to assign that key prop, that's a core React requirement which
you'll have in React for web as well.
So here, you need to point at a unique identifier and every cart item here in the end has a product ID
we can use and you can confirm this in the cart screen where you create that array of cart items in the
end, there
we store that product ID and that will be unique per row, so that is fine.
Now regarding the width of this, we can add a style here, detail items for example and add that down
there in the stylesheet
and here, simply make sure that we set a width of 100% so that we take the full available width
for the cart items. And now if we give this another try and we order this and then we go to our orders
screen and show the details,
now this looks the way it should look and now we can view the details and hide them, tiny improvement
maybe is that this text should update,
so when we view the details, this should say hide details and not show details
and of course that's also easy to implement in order items, there we have this button,
we just need to set this text dynamically and check whether show details which is our internal state
here is true.
If that's the case, then here I want to say hide details, otherwise I'll say show details
and now this text should switch dynamically as we show or hide our details.
So if we order this one last time here, we have a look at this,
now it's show details, now it's hide details, so
now this really works in the way that it should work.
Now let's also place another order, just to confirm that this really works. If we order this here, we
go to the orders screen, now you see that second order as well and you can control them independently.
So this is the order screen and how we can output orders there and how we can even reuse the cart item
here.