WEBVTT

00:00.000 --> 00:05.790
Okay, hopefully you took a look at these methods and saw how far you could get with creating the logic

00:05.790 --> 00:06.480
inside here.

00:06.480 --> 00:07.620
I'm going to go through this anyway.

00:07.620 --> 00:12.660
The idea of that was just to get you to have a think about what we might need to do, and maybe give

00:12.660 --> 00:14.010
it a go as well.

00:14.010 --> 00:16.020
The create basket, all that part.

00:16.050 --> 00:18.240
We haven't really covered what we're going to do with that.

00:18.240 --> 00:23.040
So in terms of returning the cookie etc..

00:23.040 --> 00:25.650
So we'll cover all of that in this lesson anyway.

00:25.650 --> 00:28.080
So the first step is to get the basket.

00:28.080 --> 00:33.600
And we've got a couple of items here where we need to get the basket for the add and remove items.

00:33.600 --> 00:37.740
So we'll make this a reusable method.

00:37.740 --> 00:44.610
So I'm going to say var basket equals and I'll just say retrieve basket as the name of the method.

00:44.610 --> 00:50.040
And this is going to need to be an async method because we're going to make a call to our database.

00:50.040 --> 00:52.410
So I'll use await inside there as well.

00:52.410 --> 00:57.810
Now we don't need any parameters or arguments for this method because we're going to get the basket

00:57.990 --> 00:59.760
from the cookies.

00:59.760 --> 01:05.540
So I'm just going to put my cursor inside there and generate the method to do this, and I don't like

01:05.540 --> 01:06.260
its position there.

01:06.260 --> 01:10.400
I'm just going to cut this and put it below the delete method.

01:11.150 --> 01:19.010
So inside this method then to retrieve the baskets we are going to return a basket from this.

01:19.010 --> 01:20.810
So I'm going to specify task.

01:20.810 --> 01:23.900
And inside the task I'm going to specify basket.

01:24.140 --> 01:26.900
But we may or may not have the basket from this.

01:26.900 --> 01:31.520
So I'm going to make it optional so that we can return null from this particular method.

01:31.520 --> 01:36.230
And then we'll just check for the existence of the basket in the method where we use it.

01:36.230 --> 01:42.620
So from here we're going to return await and context dot baskets.

01:42.710 --> 01:45.410
And we need to include the items.

01:45.410 --> 01:48.380
So I'll say x goes to x dot items.

01:48.410 --> 01:53.900
And we'll use let include and say x goes to x dot products.

01:54.260 --> 01:57.620
And then we'll use first or default async.

01:57.770 --> 02:01.160
And we'll specify x goes to x dot baskets id.

02:01.190 --> 02:10.910
That's equal to the request Dough cookies, and in square brackets we're going to have the basket ID

02:11.390 --> 02:13.880
pretty much the same method we used above actually.

02:13.880 --> 02:19.670
So we can also in this case use the same method here.

02:19.670 --> 02:26.900
And instead of using all of that, we can just use a weight and retrieve baskets up here as well.

02:26.900 --> 02:29.690
And then take this line and copy it.

02:29.690 --> 02:34.370
And well we've already got it in the add item to basket.

02:34.370 --> 02:38.720
And then we can go back down to our add item to basket.

02:38.720 --> 02:41.810
So we need to check to see if we have a basket.

02:41.810 --> 02:45.830
And if we do not we're going to need a method to create a basket.

02:45.830 --> 02:48.620
So we can use an if statement here.

02:48.620 --> 02:53.090
And we can check to see if the basket is equal to null and then create the basket.

02:53.090 --> 02:56.690
But I just want to demonstrate another shorthand way of doing such a thing.

02:56.690 --> 02:58.580
So we can specify basket.

02:58.580 --> 03:03.800
And then we can use double question mark which will check it for null.

03:03.800 --> 03:10.460
And if it is null then we can assign In basket to a method that will call create basket.

03:10.460 --> 03:13.880
And what we return from this is going to be a new basket.

03:13.880 --> 03:19.430
So if the basket is null, then we're going to set it equal to what this returns, which is what we're

03:19.430 --> 03:20.270
about to create now.

03:20.270 --> 03:23.480
So I'll just put my cursor inside this method and generate the method.

03:23.480 --> 03:29.330
And then once again I'm just going to cut this and reposition it below the endpoints.

03:29.330 --> 03:34.850
So we've got our methods for the logic separate at the bottom here.

03:34.880 --> 03:38.870
Now this one has automatically generated the question mark there.

03:38.870 --> 03:41.600
But we do not want to return null from this.

03:41.600 --> 03:43.490
We do want to return the basket from this.

03:43.490 --> 03:47.360
We want to ensure it has been created when we do this.

03:48.410 --> 03:52.070
So inside this method we will create a basket ID.

03:52.130 --> 03:54.620
So I'm going to say var basket id equals.

03:54.620 --> 04:00.680
And we can use Guid and then say new guides and open parentheses.

04:00.680 --> 04:05.660
And because we want this to be a string instead of a Guid object, then we're going to use the two string

04:05.660 --> 04:07.610
method on this.

04:08.180 --> 04:13.070
And we're going to create some cookie options because we are going to return this as a cookie.

04:13.100 --> 04:20.210
So I'll say var cookie options equals new cookie options.

04:20.210 --> 04:24.980
And inside here we're going to specify that this cookie is essential.

04:24.980 --> 04:31.250
And we're going to say true because users have the ability to turn off cookies or something along those

04:31.250 --> 04:31.700
lines.

04:31.700 --> 04:38.270
And we want to say hey, for this particular cookie it's essential to the operation of our application.

04:38.270 --> 04:41.420
And basket functionality is essential.

04:41.420 --> 04:47.240
So even if when they see that cookie banner, which is quite prevalent nowadays in many websites and

04:47.240 --> 04:53.990
they say, no, I don't want any cookies going on, this one would still be usable inside the application,

04:53.990 --> 05:00.320
and we're going to give it an expires property equal to date time dot now.

05:00.320 --> 05:06.290
Or let's use UTC now in our application to be consistent with the date times, no matter where it is

05:06.290 --> 05:12.860
in the world, UTC is a standard time zone for the entire planet, so we'll use that rather than the

05:12.860 --> 05:15.350
local version, which would be datetime.now.

05:15.350 --> 05:21.590
And then we'll specify add days and we'll just pick an arbitrary number of 30 for this, that that's

05:21.590 --> 05:24.950
how long this cookie is going to survive for in the user's browser.

05:24.950 --> 05:30.110
If they don't do anything to update it, then we're going to specify response.

05:30.110 --> 05:33.710
So we do something with our HTTP request response.

05:33.710 --> 05:37.310
We're going to say response dot cookies dot append.

05:37.310 --> 05:43.910
And we're going to specify baskets id and then pass in the basket ID.

05:44.150 --> 05:47.990
And then as a third parameter we're going to pass in the cookie options.

05:48.080 --> 05:51.260
Now here once again is your string warning.

05:51.260 --> 05:55.160
Because strings are easy to make mistakes with.

05:55.160 --> 05:56.900
And we don't get any compiler warning.

05:56.900 --> 06:02.720
So please do double check your usage of basket ID and ensure it matches everywhere else we've used it

06:02.720 --> 06:03.980
inside here.

06:04.280 --> 06:10.580
Following this we can specify var baskets equals new basket.

06:12.680 --> 06:19.640
And all we need to do when we create a new basket is provide the basket ID and set it to the basket

06:19.640 --> 06:21.560
ID we've created above.

06:22.400 --> 06:27.200
And we're not getting any warnings here, which means we have met the requirements for creating a new

06:27.200 --> 06:28.130
basket.

06:28.160 --> 06:32.930
Following that, we can tell Entity Framework to start tracking this basket.

06:32.930 --> 06:39.620
And the way that we do that, we say context dot baskets, dot ads and pass in basket.

06:39.620 --> 06:44.090
And then we can return the baskets from this method.

06:44.120 --> 06:46.550
So at this point we're doing nothing with the database.

06:46.550 --> 06:51.260
We're simply asking Entity Framework to track this new basket in memory.

06:51.290 --> 06:58.730
And if we go back up to our ad basket item then now our basket is either the one we've got from our

06:58.730 --> 07:02.240
database or it's the one that we've just created.

07:02.270 --> 07:06.050
So then we need to go and get the product that we want to add.

07:06.050 --> 07:07.730
And we've got the product ID here.

07:07.730 --> 07:18.610
So let's go to the database again and we'll specify var product equals Awaits and context dot products.

07:18.610 --> 07:24.100
And for this one, because we want to get the product by its primary key, effectively, we can actually

07:24.100 --> 07:27.100
use the find async method.

07:27.100 --> 07:34.120
This particular method in Entity Framework only will find an entity with the given primary key values.

07:34.120 --> 07:39.790
If we want to get an entity based on one of its other properties, then we have to use Firstordefault

07:39.790 --> 07:46.630
or single or default, but we can use find async if we do know the primary key ID of that entity.

07:46.630 --> 07:50.380
So we can use the product ID inside here to find it.

07:50.410 --> 07:54.340
Now we have no guarantee that that product exists in the database.

07:54.340 --> 07:56.020
So this product could be null.

07:56.020 --> 07:58.750
So we need to check at this point.

07:58.750 --> 08:03.100
And we'll check to see if the product is equal to null.

08:03.340 --> 08:07.420
And if so then we're going to return a bad request at this point.

08:07.420 --> 08:15.610
And we're just going to say problem adding basket to or problem adding item to basket would make more

08:15.610 --> 08:17.260
grammatical sense.

08:19.360 --> 08:24.460
So with in the last section, we've dealt with handling HTTP response errors.

08:24.460 --> 08:28.450
And we know what's going to happen if we do return a bad request.

08:28.450 --> 08:33.970
At this point, that's going to pop up a toast to the user to notify them that there was an issue with

08:33.970 --> 08:38.920
trying to add this item, because if we don't have the product in the database, we cannot add it to

08:38.950 --> 08:39.760
our basket.

08:39.790 --> 08:44.560
Of course, the next step then is to add the item to the basket.

08:44.560 --> 08:48.460
And we created a method inside our entity to do this.

08:48.460 --> 08:50.830
So we can specify basket add item.

08:50.830 --> 08:52.810
And this takes two parameters.

08:52.810 --> 08:56.080
It takes the product and it takes the quantity.

08:56.110 --> 09:00.610
So we can pass in the product and the quantity inside there.

09:00.640 --> 09:07.840
And then in order to update our database we do need to save our changes into the database.

09:07.840 --> 09:12.970
So we're going to check this as well to make sure that something has been updated in our database.

09:12.970 --> 09:20.500
So we'll use var result then say await context and save changes Is a sink.

09:20.500 --> 09:27.010
So all of the changes that have been saved in memory, perhaps we've got a new basket that we're creating.

09:27.130 --> 09:30.340
Perhaps we've added something to that basket.

09:31.120 --> 09:36.190
Then all of those changes get saved inside this method.

09:36.220 --> 09:42.940
Now, the way that this works with our Dbcontext and Entity Framework, I mentioned earlier that this

09:42.940 --> 09:44.050
uses a couple of patterns.

09:44.050 --> 09:47.350
It uses a repository pattern and a unit of work pattern.

09:47.350 --> 09:55.030
And the idea, the big idea with the unit of work pattern is that all of our changes are tracked.

09:55.750 --> 10:01.630
And then if one of those changes fails, then they all fail and everything gets rolled back to the state

10:01.630 --> 10:04.660
that it was in before we started making changes.

10:05.320 --> 10:09.970
But if they all succeed, then this save changes method will succeed.

10:10.000 --> 10:18.190
So everything inside here is effectively a transaction and transactions.

10:18.220 --> 10:22.150
Either all the changes have to succeed or none of them succeed.

10:22.150 --> 10:27.400
and that's what we really try and achieve when using the unit of work pattern.

10:27.400 --> 10:34.450
But that's already included with Entity Framework and that dbcontext then we can check the results.

10:34.450 --> 10:39.010
And the results, by the way, is going to be an integer.

10:39.010 --> 10:44.080
If we take a look at what this actually returns, then this returns an int.

10:44.110 --> 10:49.210
And this int represents the number of changes that were made into our database.

10:49.210 --> 10:54.970
So all we need to do to check that something is changed in our database is just make sure that number

10:54.970 --> 10:57.790
of changes is greater than zero.

10:57.790 --> 11:04.000
It doesn't matter if it's one, two, five, 50 changes based on what I was saying earlier, if one

11:04.000 --> 11:05.710
change fails, they all fail.

11:05.710 --> 11:10.240
Then we only care if more than zero changes have occurred in our database.

11:10.240 --> 11:16.840
So this will result in true if the changes are greater than zero.

11:16.930 --> 11:19.180
So we can specify if results.

11:19.180 --> 11:25.720
And we're effectively checking to make sure the boolean is equal to true if we just say result that

11:25.720 --> 11:28.720
is effectively equal to saying this.

11:28.720 --> 11:31.390
But we don't need to specify double equals true.

11:31.390 --> 11:43.240
There we can return a created at action result that's going to return to us a 201 and a created action

11:43.240 --> 11:48.190
results will return the thing that we're going to return.

11:48.190 --> 11:52.810
I did mention we're not going to return the basket earlier, but I think we will return the basket as

11:52.810 --> 11:57.610
well at this stage, even though our client doesn't actually need it, because we can handle the changes

11:57.610 --> 11:59.050
locally on the client.

11:59.050 --> 12:04.450
For this example, whilst we're developing our API, I think I am going to return the basket as well.

12:04.450 --> 12:05.860
So the created an action.

12:05.860 --> 12:11.860
It also returns a location header of how to get the thing that's been updated or added.

12:11.860 --> 12:18.730
So we want in this case we want to return the get basket and we return a location header with the response

12:18.730 --> 12:23.080
which will take a look at when we test this in postman of where to get the basket from.

12:23.080 --> 12:28.120
So that's going to be localhost 5001 API forward slash basket.

12:28.630 --> 12:30.700
And that would retrieve the basket.

12:30.700 --> 12:33.880
And that's the location header we want to send back with this response.

12:33.910 --> 12:38.800
Don't worry if that's not 100% clear because it will be once we test this method.

12:38.830 --> 12:40.750
So we give it a name of get basket.

12:40.750 --> 12:47.380
This is the action when we say created an action, this is the action that contains the location, the

12:47.380 --> 12:50.860
endpoint of how to get the basket that has been updated.

12:50.890 --> 12:55.420
And then in the second parameter, we can just pass in the basket as the thing that we are going to

12:55.420 --> 12:56.230
return.

12:56.350 --> 13:06.790
Now if results is false and not true, then we will return a bad request because we didn't save the

13:06.790 --> 13:08.440
changes into the database.

13:08.440 --> 13:13.390
And I'm just going to say problem updating basket for this one.

13:13.450 --> 13:18.220
So now that we've got something some logic in our code and we've got our controller endpoint, what

13:18.220 --> 13:23.170
we'll do is we'll take a look at this through the debugger next so that we can see what's going on as

13:23.200 --> 13:26.350
we're adding an item into our basket.

13:26.680 --> 13:29.380
And we'll take a look at that next.
