WEBVTT

00:00.020 --> 00:04.310
Okay, so our next task is to deal with the product details component.

00:04.310 --> 00:10.220
And of course we've got a text input here where we can define the quantity in the basket with a counter

00:10.220 --> 00:11.660
because this is a number.

00:11.660 --> 00:14.360
And then a button to add it to the basket.

00:14.840 --> 00:19.550
And what we would ideally like to do is to be able to use this component.

00:19.550 --> 00:25.730
So if they do go down to zero then we update the basket and it removes the item from the basket.

00:25.730 --> 00:32.090
And of course we want them to be able to change the quantity and reflect that in the nav bar and the

00:32.090 --> 00:34.970
order summary and our basket component.

00:34.970 --> 00:36.290
And do all of that.

00:36.290 --> 00:42.680
So slightly trickier, because we need to create the logic inside this component to handle these different

00:42.680 --> 00:47.930
scenarios where we remove the item, reduce or increase its quantity by a certain amount.

00:47.930 --> 00:53.780
And we've also got a text input this time to think about as well, and how we deal with that in a react

00:53.780 --> 00:54.740
component.

00:54.740 --> 00:59.780
Just to point out, first of all, I can click up and down inside this component right now because react

00:59.780 --> 01:01.100
is unaware of it.

01:01.100 --> 01:04.610
This is referred to as an uncontrolled component in react.

01:04.610 --> 01:10.370
And if I go back to the code and this tidy things up at the top, and I'll just head over to the product

01:10.370 --> 01:17.180
details component inside the code where we've got that text inputs or the text field, I should say

01:17.180 --> 01:18.650
in material UI.

01:18.680 --> 01:21.140
Then we've given this a default value.

01:21.170 --> 01:26.210
Now when we use default value, you can pretty much say, well this is an uncontrolled component.

01:26.210 --> 01:28.490
React doesn't know about this.

01:28.490 --> 01:29.690
And in fact it does.

01:29.720 --> 01:31.250
Tell us on the description here.

01:31.250 --> 01:37.850
Use when the component is not controlled and not controlled means react does not know what this value

01:37.850 --> 01:38.720
is.

01:39.140 --> 01:42.230
Now we're going to change this to a controlled component.

01:42.230 --> 01:46.970
And the way that we would do that is we would give it the value property instead of default value.

01:46.970 --> 01:52.220
But what this does if I go back to the component is I've now broken my input.

01:52.220 --> 01:57.080
I can't go up, I can't go down, I can't change it using the keyboard.

01:57.080 --> 02:02.000
And I think we get a warning about this in the console as well, do we?

02:02.030 --> 02:02.930
We do not.

02:02.960 --> 02:03.440
Okay.

02:03.470 --> 02:04.250
React 19.

02:04.280 --> 02:06.320
I'm sure we used to get a warning about this sort of thing.

02:06.350 --> 02:07.970
Maybe if I click no, we do not.

02:08.000 --> 02:09.890
But this is just not working.

02:09.920 --> 02:10.670
Text field now.

02:10.670 --> 02:15.950
So effectively we need to track the value of this component in react state.

02:16.550 --> 02:22.550
The text field component I mean and then we can use that value to get the value and update our basket.

02:22.550 --> 02:27.470
So we're going to use a controlled component or controlled text field component for this.

02:27.470 --> 02:31.070
And we've started that process by specifying the value here.

02:31.100 --> 02:37.190
Now we would like to get that value of course from our basket to see if we've already got an item of

02:37.190 --> 02:40.460
this type in our basket and update that accordingly.

02:40.730 --> 02:47.840
So we're going to need to add a bit of functionality inside what is already quite a busy component,

02:47.900 --> 02:49.010
but we'll persevere.

02:49.040 --> 02:55.700
So first of all, we need to use the two mutation functions to either remove or add an item from our

02:55.700 --> 02:56.090
basket.

02:56.090 --> 03:00.200
So we'll set those up and we'll have the remove basket item function.

03:00.200 --> 03:04.940
And I'm going to set that equal to use remove basket item mutation.

03:04.940 --> 03:13.970
And we'll also have the add basket item function, and we'll set that to use add basket item mutation.

03:15.350 --> 03:19.190
And we're also going to need the basket as well.

03:19.880 --> 03:24.170
So inside here I'll specify const and say data.

03:24.170 --> 03:27.710
And we'll give it the name of basket because we've got data down here.

03:27.710 --> 03:29.900
But we have specified products for that one.

03:30.350 --> 03:34.430
And we'll use the use fetch basket query.

03:34.460 --> 03:41.000
And then we'll need to get the item from the basket so that we can find out if that item is indeed in

03:41.000 --> 03:41.540
the basket.

03:41.570 --> 03:45.020
So we'll create a const for this and say const item equals.

03:45.110 --> 03:50.990
And we'll use baskets dot items dot find.

03:51.500 --> 04:00.800
And we're going to look for the item that has x dot product ID that's equal to the ID inside our parameters.

04:01.040 --> 04:05.960
And we've got a warning here that says this comparison appears to be unintentional because the types

04:05.960 --> 04:09.050
number and string or undefined have no overlap.

04:09.050 --> 04:11.300
So our ID is a string in our URL.

04:11.330 --> 04:14.300
So let's see if we can get away with using the plus symbol.

04:14.300 --> 04:15.290
We can.

04:15.380 --> 04:19.160
And on this occasion we could be a bit more.

04:19.190 --> 04:23.840
In fact, we cannot be a bit more defensive up here because what's going on with these hooks.

04:23.930 --> 04:26.840
We cannot call any of these conditionally.

04:26.840 --> 04:28.790
And we've got a hook down here as well.

04:28.790 --> 04:31.220
And none of these can be conditional.

04:31.220 --> 04:36.500
So if we add an if statement to check to see if we have the ID inside our code here we're going to run

04:36.500 --> 04:41.780
into some TypeScript difficulties with the way that react hooks work.

04:41.870 --> 04:47.090
They cannot be hidden behind the conditional, and we will always get a warning if we try to do so in

04:47.090 --> 04:47.810
react.

04:47.810 --> 04:54.080
So on this occasion, I'm going to use the overrides to tell TypeScript that I do not want this warning

04:54.110 --> 05:02.660
to display here, and I know that the ID could possibly be undefined, so I'm going to use the exclamation

05:02.660 --> 05:08.750
mark there just to take away the warning, because if we don't find an item that matches or we don't

05:08.770 --> 05:14.860
have a basket, then the item is effectively just going to be undefined and I'm okay with that.

05:14.860 --> 05:19.000
And then also inside here we're going to have some state to set the quantity.

05:19.030 --> 05:23.110
So we'll have const quantity and set quantity.

05:26.020 --> 05:27.880
And let's try and spell it correctly.

05:27.880 --> 05:30.730
And I'll set this to use states.

05:31.000 --> 05:34.720
And we're going to give this an initial value of just zero.

05:36.610 --> 05:42.400
Now when our component loads we would like to be able to set the quantity if we do have the item.

05:42.400 --> 05:49.210
So in order to add a side effect into our component, we'll add a use effect here.

05:49.960 --> 05:56.470
And we will in its callback function add the dependencies afterwards.

05:56.470 --> 06:01.330
Just an empty array for this one just now, and we'll check to see if we have the item.

06:01.330 --> 06:06.580
And if we do, we're going to set the quantity to the item dot quantity.

06:06.610 --> 06:14.590
And it's telling us that we need to supply the dependency, which of course is the item in this case.

06:14.590 --> 06:18.940
Now we're also going to need a function to handle the updating of the basket.

06:18.940 --> 06:20.650
Because we've got two scenarios here.

06:20.650 --> 06:25.000
We could be reducing the quantity or adding to the quantity.

06:25.000 --> 06:33.310
So we need to compare the quantity that we use in our input and compare it to the item quantity.

06:33.460 --> 06:39.370
And if it's greater than or less than, then we either need to add or remove a basket item.

06:39.370 --> 06:42.040
So we'll create a helper function in here as well.

06:42.040 --> 06:45.010
And in fact we're going to need two helper functions.

06:45.370 --> 06:50.590
So I'll say const handle updates baskets equals.

06:50.590 --> 06:52.300
And we'll take no parameters.

06:52.330 --> 06:55.510
And we'll open curly brackets inside here.

06:55.510 --> 06:59.710
And we want to know what the updated quantity is.

06:59.800 --> 07:02.350
And we're going to set this equal to item.

07:02.470 --> 07:07.270
And we need to compare the item quantity with the quantity.

07:07.300 --> 07:10.090
And to help us with this we'll use a math function.

07:10.090 --> 07:21.580
And we'll say math Dot abs for absolutes and we'll use quantity minus item dot quantity.

07:22.450 --> 07:27.790
Or it's going to be the quantity which means it hasn't changed.

07:27.790 --> 07:29.410
So list.map absolute Len.

07:29.410 --> 07:35.920
If we hover over this then this returns the absolute value of a number, the value without regard to

07:35.950 --> 07:38.110
whether it is positive or negative.

07:38.110 --> 07:43.030
And for example, the absolute value of minus five is the same as the absolute value of five.

07:43.060 --> 07:51.460
So supposing that the quantity in this case this is what we're going to set it to is five.

07:51.460 --> 08:00.010
And let's supposing the item quantity, what we currently have inside our basket is three.

08:00.010 --> 08:02.950
So we want to go from 3 to 5.

08:03.280 --> 08:06.610
Then in this example it would be.

08:06.640 --> 08:11.620
And if we take a look at how we're using this function we're specifying quantity minus item quantity.

08:11.650 --> 08:18.100
So that would be in this case it would be five minus three and that would give us.

08:18.250 --> 08:20.800
Obviously that would give us two.

08:20.830 --> 08:22.960
But supposing it was the other way round.

08:22.960 --> 08:30.130
And supposing our quantity that we currently have is three, or the quantity in the inputs is three,

08:30.130 --> 08:38.110
and we currently have five in our basket, then the calculation in this case would be three minus five

08:38.320 --> 08:40.450
which would give us minus two.

08:40.480 --> 08:47.440
But when we use the absolute function we effectively return two, which means that we change that into

08:47.470 --> 08:52.480
a positive number, which means we would be removing two items from our cart.

08:52.510 --> 08:58.930
So let's just a brief explanation of the math absolute that we're using inside here.

08:58.960 --> 09:04.090
So now we have that we can check to see if we're adding or removing from our basket.

09:04.090 --> 09:07.660
So we'll check and we'll check to see if we do not have an item.

09:08.620 --> 09:12.100
Then obviously we're going to be adding to our basket at this point.

09:12.130 --> 09:17.260
Or the quantity is greater than the item quantity.

09:17.290 --> 09:21.910
Then we're adding something to our basket so we can use the add basket item method.

09:21.910 --> 09:31.240
And in curly brackets we can specify the product and the quantity which will set to the updated quantity.

09:31.480 --> 09:36.070
And we don't have access to the product at this point, which means I need to move my function below

09:36.070 --> 09:37.330
where we're getting the product.

09:37.360 --> 09:39.640
So I've got the const handle update basket here.

09:39.670 --> 09:45.070
I just need to move it below the if statement in fact, because at this point we'll definitely have

09:45.070 --> 09:45.610
the product.

09:45.610 --> 09:47.980
So I'll just paste in the function there.

09:47.980 --> 09:49.270
And then our warning goes away.

09:49.270 --> 09:52.390
We've still got a warning because we haven't used it yet in our code.

09:52.450 --> 10:00.430
Now we also need to handle the change of an input so that we can use the set quantity function based

10:00.430 --> 10:02.080
on an input changing.

10:03.130 --> 10:12.100
So inside here as well, we'll add another function and say const handle inputs change equals and I'll

10:12.100 --> 10:13.060
just use event.

10:13.060 --> 10:16.810
And for the time being I'll just use any and come back and correct this very soon.

10:16.810 --> 10:20.440
And we'll add the arrow and open curly brackets.

10:20.440 --> 10:23.230
And we need to get the value of the input.

10:23.230 --> 10:25.960
So we'll say const value equals.

10:27.460 --> 10:32.890
And if we take a look at what we get for the event then because I've given it the any type, I don't

10:32.890 --> 10:34.630
have access to its properties.

10:34.630 --> 10:39.820
So if we go down to the text fields and take a look at a text field, we'll just give it an Onchange

10:39.820 --> 10:40.780
event.

10:40.930 --> 10:45.670
As this is the event, we're going to be passing to our function and say handle input change.

10:45.670 --> 10:50.800
If we hover over the onchange, then we can see what type of event this outputs.

10:50.800 --> 10:54.460
And it's going to be an HTML input element event.

10:54.640 --> 10:57.370
And we're using a react change event here.

10:57.370 --> 11:00.460
So we can give this a type for our function.

11:00.460 --> 11:04.120
And we'll come back to the handle input change.

11:05.170 --> 11:11.710
And the event type we're going to be using is going to be a change event which we get from react.

11:11.710 --> 11:20.200
And it's going to be of type Htmlinputelement and this will give us the event properties that we have

11:20.200 --> 11:21.160
access to.

11:21.190 --> 11:27.280
So we want to use the event current target dot value here.

11:27.280 --> 11:33.070
And then we want to check to see if the value is greater than or equal to zero.

11:33.070 --> 11:39.610
And then we'll set the quantity because we don't want them to be able to specify a minus number in our

11:39.610 --> 11:40.090
input.

11:40.090 --> 11:43.900
So we'll check to see if the value is greater than or equal to zero.

11:44.020 --> 11:48.520
And if it is then we're going to set the quantity to the value.

11:48.520 --> 11:54.340
And we've got a warning here no doubt because the value as coming in as a string.

11:54.340 --> 11:56.980
And we want to cast this into a number.

11:57.100 --> 11:59.230
So we use the plus symbol there.

11:59.230 --> 12:00.910
And now our value is a number.

12:00.910 --> 12:03.280
And we can check to see if it's greater than zero.

12:03.280 --> 12:06.340
If it is at that point we set the quantity.

12:06.340 --> 12:09.100
So back down to our text field.

12:09.130 --> 12:09.670
Then.

12:09.670 --> 12:14.950
And instead of one we'll set this to the quantity.

12:14.950 --> 12:18.490
So if they don't have it in our basket it's default value is zero.

12:18.490 --> 12:23.500
And as we change the quantity, then we should see that changing in the component as well.

12:24.010 --> 12:33.490
Also, inside our button we'll use an onClick event and we'll use the handle update basket method.

12:33.490 --> 12:41.200
And we'll also disable the button if and we'll add the equals and curly brackets.

12:41.200 --> 12:49.240
And we'll disable the button is if if the quantity is equal to the item dot quantity, we don't want

12:49.270 --> 12:50.200
them to click it.

12:50.200 --> 13:02.770
If nothing's going to change or there is no item and the quantity is equal to zero, so that means they

13:02.770 --> 13:04.480
don't have it currently in our basket.

13:04.480 --> 13:09.310
And we don't want the button to be enabled so they can click on it if they haven't actually specified

13:09.310 --> 13:12.730
more than zero to add to the basket.

13:12.730 --> 13:14.380
And I've got some warnings inside here.

13:14.380 --> 13:16.390
Let's see what those are about.

13:16.390 --> 13:18.700
And we've got the remove basket item.

13:18.730 --> 13:22.470
Of course we've only done one side of the handle update basket.

13:22.470 --> 13:27.510
So those warnings, even though they're noisy, they can be quite useful because that's told me I've

13:27.510 --> 13:28.560
forgotten to do something.

13:28.560 --> 13:31.890
So we need to add inside here.

13:32.520 --> 13:34.260
The else condition of course.

13:34.290 --> 13:35.580
So we'll specify else.

13:35.580 --> 13:38.370
And then we can use the remove basket item.

13:38.370 --> 13:41.340
And this one takes in the product ID.

13:41.670 --> 13:47.340
And that's going to be the product.id and also the quantity.

13:47.580 --> 13:51.330
We can just use the updated quantity inside there.

13:51.360 --> 13:54.750
So let's take a look at our progress.

13:54.750 --> 13:58.290
And if we go back to this we can see if I well let's just refresh the page.

13:58.290 --> 14:01.620
First of all we can see that I don't currently have this in my basket.

14:01.620 --> 14:06.900
Let's just check the basket to make sure I've only got a green woollen hat inside there.

14:06.900 --> 14:10.920
So if I go back then I should be able to increase the quantity.

14:10.920 --> 14:13.200
And then we get the add to basket button.

14:13.200 --> 14:20.250
And if I do add to baskets then we can see that we've now got three inside here in the nav bar.

14:20.250 --> 14:23.160
And I've got the quantity of one inside here as well.

14:23.160 --> 14:26.220
If I refresh the page then that stays the same.

14:26.220 --> 14:30.840
The quantity is one and if I increase then I can add to basket.

14:30.840 --> 14:34.650
Maybe I'd like to change that to update basket if we do have the item.

14:34.650 --> 14:38.790
So I'll just head back to VS code to make that small change.

14:38.790 --> 14:43.500
So we'll go down to the button where we've got the label, and we'll just check to see if we have the

14:43.500 --> 14:44.340
item.

14:45.300 --> 14:54.180
And if we do, we're going to specify update quantity as the label or add to basket if we do not have

14:54.180 --> 14:54.870
the item.

14:54.870 --> 15:00.030
And if I go back and take a look, then we can see that's set to update quantity now, which makes a

15:00.030 --> 15:01.560
bit more sense.

15:01.620 --> 15:05.340
And we should be able to reduce this to zero.

15:05.370 --> 15:08.580
And that should remove it from our cart.

15:08.580 --> 15:12.870
So if I just check we're looking at the green angular board I'll go to the shopping cart.

15:12.900 --> 15:14.790
I can see I've got two of these in there.

15:14.790 --> 15:23.880
Now if I go back and I reduce this to zero update quantity, the cart gets updated and is removed from

15:23.880 --> 15:24.990
here as well.

15:24.990 --> 15:28.530
But what do we see if we remove the green woolen hats?

15:29.040 --> 15:29.640
Hmm.

15:30.120 --> 15:32.160
We still see the order summary.

15:33.210 --> 15:39.210
Our basket is technically empty, but I don't see anything in the background.

15:39.240 --> 15:40.620
Do I want that kind of behavior?

15:40.650 --> 15:41.310
Not really.

15:41.310 --> 15:45.840
So let's head back to the basket page and make a small adjustment there as well.

15:45.840 --> 15:54.120
And when we empty out a basket we do have the basket, but it's just got no items in the basket.

15:54.120 --> 15:56.550
So we'll just check the items length as well here.

15:56.550 --> 16:04.290
So I'll check the if no data or data dot items dot length is equal to zero.

16:04.320 --> 16:10.680
Then we'll just return the your basket is empty there and that's more like it if we go back to the catalog

16:10.680 --> 16:14.430
and let's just add something to the cart, then we see that popping in there.

16:14.460 --> 16:15.180
Okay.

16:15.210 --> 16:16.140
Marvelous.

16:16.950 --> 16:20.730
And the only thing I really want to take a look at next is the checkout.

16:20.730 --> 16:24.570
And we'll start to implement that, although only the very beginnings of it.

16:24.570 --> 16:26.640
And we'll take a look at that next.
