1
00:00:02,350 --> 00:00:04,470
Now, how do we get to this product

2
00:00:04,470 --> 00:00:06,803
in this cart controller action here?

3
00:00:07,939 --> 00:00:10,680
Well, we'll need to get it from the database.

4
00:00:10,680 --> 00:00:15,680
So here we'll actually import my product model because that

5
00:00:16,129 --> 00:00:18,890
has to methods for talking to the database

6
00:00:18,890 --> 00:00:20,620
and fetching product data.

7
00:00:20,620 --> 00:00:22,462
So I'll import this,

8
00:00:22,462 --> 00:00:25,930
turn add cart item into an async function.

9
00:00:25,930 --> 00:00:29,630
Since we'll perform an asynchronous operation.

10
00:00:29,630 --> 00:00:32,610
And the asynchronous operation I want to perform

11
00:00:32,610 --> 00:00:35,130
is that I use product find by ID

12
00:00:35,130 --> 00:00:37,481
to find a specific product by ID,

13
00:00:37,481 --> 00:00:40,673
and then use that product to add it to the cart.

14
00:00:41,810 --> 00:00:43,080
Now for that here,

15
00:00:43,080 --> 00:00:45,800
the ID which I expect to get

16
00:00:45,800 --> 00:00:47,958
should be found in the request body,

17
00:00:47,958 --> 00:00:50,440
because I won't send a get request,

18
00:00:50,440 --> 00:00:53,980
but a post request for adding a new cart item.

19
00:00:53,980 --> 00:00:56,900
Post makes sense because we're adding,

20
00:00:56,900 --> 00:00:59,020
creating new data on the server.

21
00:00:59,020 --> 00:01:01,130
That's a typical case for a post,

22
00:01:01,130 --> 00:01:03,240
and therefore we'll have a request body

23
00:01:03,240 --> 00:01:06,420
attached to the incoming request, because post requests

24
00:01:06,420 --> 00:01:09,630
do have bodies, unlike get requests.

25
00:01:09,630 --> 00:01:11,600
And in this post request body,

26
00:01:11,600 --> 00:01:14,680
I expect to find the product ID.

27
00:01:14,680 --> 00:01:16,250
I can use that here therefore,

28
00:01:16,250 --> 00:01:17,880
and then await this,

29
00:01:17,880 --> 00:01:20,763
to get the product that should be added.

30
00:01:22,360 --> 00:01:24,120
As always, this might fail,

31
00:01:24,120 --> 00:01:26,220
So let's try this,

32
00:01:26,220 --> 00:01:28,740
and catch this error,

33
00:01:28,740 --> 00:01:32,980
and now we do need the next parameter value,

34
00:01:32,980 --> 00:01:36,293
not for add item to cart, but for fetching a product.

35
00:01:37,200 --> 00:01:39,030
So in the catch case here,

36
00:01:39,030 --> 00:01:43,060
I want to call next error and then return,

37
00:01:43,060 --> 00:01:46,210
So to know ever code executes thereafter.

38
00:01:46,210 --> 00:01:48,820
And I want to use the product down here

39
00:01:48,820 --> 00:01:51,730
and I could move that line into the try block,

40
00:01:51,730 --> 00:01:53,770
but to keep that block leaner,

41
00:01:53,770 --> 00:01:56,990
I will actually add a product helper variable,

42
00:01:56,990 --> 00:01:59,680
and set that in a try block.

43
00:01:59,680 --> 00:02:02,000
This variable is now scoped to the function,

44
00:02:02,000 --> 00:02:03,930
not to the try block.

45
00:02:03,930 --> 00:02:05,940
And hence, I can use that down here

46
00:02:05,940 --> 00:02:08,789
for adding this product to my cart.

47
00:02:08,789 --> 00:02:10,103
That's the idea here.

48
00:02:11,570 --> 00:02:13,200
Now, once I did that,

49
00:02:13,200 --> 00:02:16,090
I also want to make sure that the updated cart

50
00:02:16,090 --> 00:02:19,100
is saved back into the session.

51
00:02:19,100 --> 00:02:21,880
That means I'll access my session,

52
00:02:21,880 --> 00:02:23,710
and they to cart property.

53
00:02:23,710 --> 00:02:27,890
And there, I will store res locals cart.

54
00:02:27,890 --> 00:02:30,133
So that data which had just updated,

55
00:02:31,190 --> 00:02:33,460
we can also add a utility constant here,

56
00:02:33,460 --> 00:02:36,360
which has res locals cart as a value

57
00:02:36,360 --> 00:02:37,850
so that we can actually

58
00:02:37,850 --> 00:02:40,710
work with that constant and don't type

59
00:02:40,710 --> 00:02:43,130
res locals cart all the time.

60
00:02:43,130 --> 00:02:47,200
But the idea is the same. I use that cart to add the item,

61
00:02:47,200 --> 00:02:50,690
and now that the cart is updated, I set it back,

62
00:02:50,690 --> 00:02:54,193
I override the cart in my session with that new cart.

63
00:02:55,050 --> 00:02:58,163
The cart in the session, not in res locals.

64
00:02:59,350 --> 00:03:00,874
The session cart, is the cart

65
00:03:00,874 --> 00:03:04,470
that will survive this request response cycle,

66
00:03:04,470 --> 00:03:07,763
and that will be stored in the session database collection.

67
00:03:08,660 --> 00:03:10,640
So that is my session-based data,

68
00:03:10,640 --> 00:03:14,083
which I now update after the cart was updated.

69
00:03:16,350 --> 00:03:18,450
We don't need to call req session save,

70
00:03:18,450 --> 00:03:20,650
because that will be called automatically.

71
00:03:20,650 --> 00:03:22,390
We would only have to call that,

72
00:03:22,390 --> 00:03:25,380
if we then perform an action, like a redirect,

73
00:03:25,380 --> 00:03:28,640
which relies on that data to be updated.

74
00:03:28,640 --> 00:03:31,690
So which needs to guarantee that this update was

75
00:03:31,690 --> 00:03:33,123
saved to the database.

76
00:03:34,410 --> 00:03:37,280
I don't need that here though, because

77
00:03:37,280 --> 00:03:41,570
I actually don't plan on submitting a regular forum here,

78
00:03:41,570 --> 00:03:42,960
and then in the end,

79
00:03:42,960 --> 00:03:45,450
redirecting back to this page thereafter,

80
00:03:45,450 --> 00:03:47,210
even though we could do that,

81
00:03:47,210 --> 00:03:51,230
but instead, I want to use another Ajax request here,

82
00:03:51,230 --> 00:03:53,510
so that we handle a click on this button

83
00:03:53,510 --> 00:03:56,730
with front-end browser site, JavaScript code,

84
00:03:56,730 --> 00:04:00,823
and we send such a JavaScript driven request to the backend.

85
00:04:01,820 --> 00:04:05,170
And therefore, I will then update my request session data,

86
00:04:05,170 --> 00:04:08,000
but I don't redirect here,

87
00:04:08,000 --> 00:04:11,600
instead I sent back adjacent response,

88
00:04:11,600 --> 00:04:15,800
where I will actually set the status code to 201,

89
00:04:15,800 --> 00:04:19,260
which is a success status code that also says

90
00:04:19,260 --> 00:04:23,370
successfully added data, so to say.

91
00:04:23,370 --> 00:04:26,580
Setting it is optional, 200 would be the default.

92
00:04:26,580 --> 00:04:28,070
You don't need to set that,

93
00:04:28,070 --> 00:04:32,230
you can use 201 to be very clear that the

94
00:04:32,230 --> 00:04:34,580
add a resource action succeeded.

95
00:04:34,580 --> 00:04:35,630
Just want to show it to you,

96
00:04:35,630 --> 00:04:37,750
that's why I'm including it here.

97
00:04:37,750 --> 00:04:41,950
And with that, we then sent back our data.

98
00:04:41,950 --> 00:04:44,750
Now the data I do want to send back here,

99
00:04:44,750 --> 00:04:46,410
could be a little message like

100
00:04:46,410 --> 00:04:49,410
cart updated, but more importantly,

101
00:04:49,410 --> 00:04:52,010
I want to send back data about the cart

102
00:04:52,010 --> 00:04:55,820
that I can then reflect on this user interface.

103
00:04:55,820 --> 00:04:59,190
And here, I got one thing that I want to reflect.

104
00:04:59,190 --> 00:05:02,320
Next to this cart item here in the navigation,

105
00:05:02,320 --> 00:05:04,470
I want to show a little badge,

106
00:05:04,470 --> 00:05:06,722
a little number that increases

107
00:05:06,722 --> 00:05:09,860
as I add more items to the cart.

108
00:05:09,860 --> 00:05:11,670
And that's the part of the UI,

109
00:05:11,670 --> 00:05:14,780
which I want to update with front end JavaScript

110
00:05:14,780 --> 00:05:17,133
once I added an item to the cart.

111
00:05:18,156 --> 00:05:20,670
Therefore, what I want to return here,

112
00:05:20,670 --> 00:05:25,043
as part of this response, is a key named new total items,

113
00:05:25,960 --> 00:05:27,430
the name is up to you though,

114
00:05:27,430 --> 00:05:29,770
where I do return to number of items

115
00:05:29,770 --> 00:05:31,453
that are now stored in the cart.

116
00:05:32,450 --> 00:05:34,340
And this is now tricky,

117
00:05:34,340 --> 00:05:37,930
because I can't just say cart items length

118
00:05:37,930 --> 00:05:40,650
to just count the number of items into cart,

119
00:05:40,650 --> 00:05:44,960
because you have to remember that in our cart model,

120
00:05:44,960 --> 00:05:46,250
when we add item,

121
00:05:46,250 --> 00:05:49,360
we don't always push a new item onto the array,

122
00:05:49,360 --> 00:05:52,223
instead we might've just updated an existing item.

123
00:05:53,460 --> 00:05:56,000
So therefore in the cart model,

124
00:05:56,000 --> 00:05:59,330
I actually also want to have some cart wide metadata

125
00:05:59,330 --> 00:06:02,080
that tells me the number of items in the cart

126
00:06:02,080 --> 00:06:05,690
across all product groups that I might have in there,

127
00:06:05,690 --> 00:06:09,740
and that tells me the total price for the entire cart.

128
00:06:09,740 --> 00:06:12,003
And that's then the data I want to return.

129
00:06:13,070 --> 00:06:16,440
So back in cart controller, I want to return, let's say,

130
00:06:16,440 --> 00:06:21,203
cart dot quantity or total quantity.

131
00:06:22,320 --> 00:06:24,671
This is a property that doesn't exist yet,

132
00:06:24,671 --> 00:06:27,950
but it is a property which we'll add now.

133
00:06:27,950 --> 00:06:30,540
So we want to return a total quantity,

134
00:06:30,540 --> 00:06:34,330
or we want to have a total quantity in the cart that sums up

135
00:06:34,330 --> 00:06:38,610
all the quantities of all the products we have in the cart.

136
00:06:38,610 --> 00:06:41,430
And that's a feature we don't have yet.

137
00:06:41,430 --> 00:06:44,120
To do that, We could go to our cart

138
00:06:44,120 --> 00:06:46,080
and here in the constructor,

139
00:06:46,080 --> 00:06:49,520
I now don't just expect to get an items array,

140
00:06:49,520 --> 00:06:51,360
but also a total quantity,

141
00:06:51,360 --> 00:06:55,020
which by default is zero, let's say,

142
00:06:55,020 --> 00:06:57,863
and the total price, which is zero initially.

143
00:06:59,010 --> 00:07:00,520
And that's then also data,

144
00:07:00,520 --> 00:07:03,400
which I want to set up for my entire cart

145
00:07:03,400 --> 00:07:08,270
to total quantity and the total price.

146
00:07:08,270 --> 00:07:10,713
So this should be cart wide data.

147
00:07:12,440 --> 00:07:16,100
Now of course, items might not be an empty array.

148
00:07:16,100 --> 00:07:17,100
And in that case,

149
00:07:17,100 --> 00:07:20,360
the total quantity and total price also have to be provided

150
00:07:20,360 --> 00:07:22,760
correctly to the constructor,

151
00:07:22,760 --> 00:07:26,970
but we also need to update it whenever we add a new item.

152
00:07:26,970 --> 00:07:29,170
In that case, we need to update it both

153
00:07:29,170 --> 00:07:31,140
when we pushed on new item,

154
00:07:31,140 --> 00:07:33,770
and also when we just increased the quantity

155
00:07:33,770 --> 00:07:35,693
of an already existing item.

156
00:07:36,900 --> 00:07:39,510
Now in this case, that we increased the quantity

157
00:07:39,510 --> 00:07:41,700
of already existing item,

158
00:07:41,700 --> 00:07:44,970
I want to reach out to this total quantity

159
00:07:44,970 --> 00:07:46,770
of the entire cart,

160
00:07:46,770 --> 00:07:50,513
and set this equal to this total quantity plus one.

161
00:07:51,860 --> 00:07:53,630
By the way, the shortcut for this would be

162
00:07:53,630 --> 00:07:56,330
this total quantity plus plus.

163
00:07:56,330 --> 00:07:57,870
Because we increased the quantity

164
00:07:57,870 --> 00:07:59,790
of this single product by one,

165
00:07:59,790 --> 00:08:02,110
hence the quantity of the overall cart

166
00:08:02,110 --> 00:08:03,623
has to increase by one.

167
00:08:04,960 --> 00:08:08,260
Now for the price, it's this total price

168
00:08:08,260 --> 00:08:10,580
that should be set equal to this total price,

169
00:08:10,580 --> 00:08:13,550
plus the price of that product

170
00:08:13,550 --> 00:08:16,270
of which we increased the quantity by one,

171
00:08:16,270 --> 00:08:18,263
so product dot price.

172
00:08:19,580 --> 00:08:22,743
The shortcut for this by the way, would be plus equal.

173
00:08:24,370 --> 00:08:28,960
Now that is correct if we increased the quantity like this,

174
00:08:28,960 --> 00:08:33,380
if we pushed a brand new cart item onto the cart,

175
00:08:33,380 --> 00:08:34,730
it's the same.

176
00:08:34,730 --> 00:08:37,929
It's the same, because we then still want to increase the

177
00:08:37,929 --> 00:08:41,960
quantity by one because we pushed one product onto the cart,

178
00:08:41,960 --> 00:08:44,490
and we also want to increase the price

179
00:08:44,490 --> 00:08:47,583
by the price of that product that we added.

180
00:08:48,540 --> 00:08:50,543
So it's the same logic either way.

181
00:08:52,040 --> 00:08:53,620
Therefore now, We ensure that

182
00:08:53,620 --> 00:08:55,840
these properties exist the cart,

183
00:08:55,840 --> 00:08:58,230
and hence we should be able to work with them

184
00:08:58,230 --> 00:09:00,800
in the cart controller as we do here,

185
00:09:00,800 --> 00:09:04,257
when I returned the updated total quantity,

186
00:09:04,257 --> 00:09:06,573
after adding an item to the cart.

187
00:09:08,400 --> 00:09:09,830
Now to see whether that works,

188
00:09:09,830 --> 00:09:12,040
we need to do a couple of things.

189
00:09:12,040 --> 00:09:13,900
We need to add this badge here,

190
00:09:13,900 --> 00:09:17,410
which shows the number of items, and then most importantly,

191
00:09:17,410 --> 00:09:20,890
we have to connect this button to send that post request

192
00:09:20,890 --> 00:09:24,823
to the backend and to then update the dom after we did that.

193
00:09:26,380 --> 00:09:30,980
Hence, now I do actually start with the styling,

194
00:09:30,980 --> 00:09:33,650
and I'll go to the public styles folder,

195
00:09:33,650 --> 00:09:36,240
and they're into the base CSS file,

196
00:09:36,240 --> 00:09:38,770
because I want to add another base style,

197
00:09:38,770 --> 00:09:42,330
which I'll use in other parts of the page as well.

198
00:09:42,330 --> 00:09:44,500
I'll add it here at the very bottom,

199
00:09:44,500 --> 00:09:49,070
and it's the badge class selector, which I want to add here.

200
00:09:49,070 --> 00:09:52,090
We're not using this class yet, but we'll soon do so,

201
00:09:52,090 --> 00:09:55,200
and we'll also do so in different parts of this page.

202
00:09:55,200 --> 00:09:56,620
That's why I'll make it a class,

203
00:09:56,620 --> 00:09:58,633
it's not guaranteed to be unique.

204
00:10:00,410 --> 00:10:03,130
Now this batch class will get a margin

205
00:10:04,280 --> 00:10:09,280
left of, let's say, var space two,

206
00:10:10,560 --> 00:10:12,560
then a little bit of padding

207
00:10:12,560 --> 00:10:16,270
where I actually won't use one of my predefined spaces,

208
00:10:16,270 --> 00:10:18,870
but instead zero dot one five rem,

209
00:10:18,870 --> 00:10:22,870
because I need a super tiny padding top and bottom,

210
00:10:22,870 --> 00:10:26,793
but then left and right, I will use var space four,

211
00:10:28,690 --> 00:10:31,980
and you can mix fixed hard-coded values

212
00:10:31,980 --> 00:10:35,023
with dynamic variable based values like this.

213
00:10:36,510 --> 00:10:39,590
I'll add a border radius of 10 rem,

214
00:10:39,590 --> 00:10:41,640
also not using one of my variables,

215
00:10:41,640 --> 00:10:44,460
because I need a super large border radius here

216
00:10:44,460 --> 00:10:45,970
to achieve this badge look,

217
00:10:45,970 --> 00:10:48,040
which should have totally rounded corners

218
00:10:48,040 --> 00:10:49,340
as you'll see in a second,

219
00:10:51,230 --> 00:10:53,400
and I'll use a background color of

220
00:10:53,400 --> 00:10:58,400
var color dash primary dash 500,

221
00:10:58,920 --> 00:11:00,930
and set a text color to

222
00:11:00,930 --> 00:11:05,930
var color dash primary dot 500 dash contrast.

223
00:11:07,770 --> 00:11:09,260
That's my badge,

224
00:11:09,260 --> 00:11:13,140
and that's all I want to do for the badge here.

225
00:11:13,140 --> 00:11:17,010
And now I want to use that badge here in my navigation.

226
00:11:17,010 --> 00:11:20,880
So in the shared includes folder in nav items,

227
00:11:20,880 --> 00:11:23,113
and they're next to the cart.

228
00:11:24,850 --> 00:11:27,210
Here after the word cart,

229
00:11:27,210 --> 00:11:31,530
I want to add a little span with a class of badge,

230
00:11:31,530 --> 00:11:33,800
which is that class we just worked on,

231
00:11:33,800 --> 00:11:36,840
which will include the number of items in the cart.

232
00:11:36,840 --> 00:11:38,780
And that might be zero initially,

233
00:11:38,780 --> 00:11:41,280
though we will soon set that dynamically,

234
00:11:41,280 --> 00:11:43,853
but initially, if I reload, you'll see it's zero.

235
00:11:45,080 --> 00:11:46,650
Now I actually got an error here,

236
00:11:46,650 --> 00:11:48,340
we'll look into that in a second,

237
00:11:48,340 --> 00:11:49,690
but you see the badge here.

238
00:11:50,570 --> 00:11:53,350
Now let's see why I'm getting an error here.

239
00:11:53,350 --> 00:11:57,493
I do get that because cart is not a constructor.

240
00:11:59,440 --> 00:12:02,540
That has to occur in my custom middleware.

241
00:12:02,540 --> 00:12:05,170
Let's see what's wrong there.

242
00:12:05,170 --> 00:12:09,120
Cart require models, cart model?

243
00:12:09,120 --> 00:12:11,530
If I have a look at the cart model,

244
00:12:11,530 --> 00:12:13,700
yeah, I should export it there.

245
00:12:13,700 --> 00:12:17,570
That's of course missing in the cart model dot JS file,

246
00:12:17,570 --> 00:12:21,660
we should add module exports equals cart.

247
00:12:21,660 --> 00:12:23,210
Otherwise you see what's happening

248
00:12:23,210 --> 00:12:26,040
If you try to use a feature defined in another file,

249
00:12:26,040 --> 00:12:27,890
that's not being exported.

250
00:12:27,890 --> 00:12:32,460
You can't use it, but with that, reloading works again.

251
00:12:32,460 --> 00:12:35,250
And now of course the batch number should be set

252
00:12:36,110 --> 00:12:38,190
with the real cart data.

253
00:12:38,190 --> 00:12:41,083
So they offer back in nav items.

254
00:12:42,010 --> 00:12:44,410
Instead of hard coding zero here,

255
00:12:44,410 --> 00:12:49,040
I'll use ejs to output local dot cart.

256
00:12:49,040 --> 00:12:52,660
Remember, we set res locals cart in our custom cart,

257
00:12:52,660 --> 00:12:55,320
middleware dot total quantity.

258
00:12:55,320 --> 00:12:59,080
This brand new property we added a couple of minutes ago.

259
00:12:59,080 --> 00:13:00,163
I'll use it here.

260
00:13:01,150 --> 00:13:02,500
And if I reload,

261
00:13:02,500 --> 00:13:05,853
this is still zero, because initially it's zero.

262
00:13:06,750 --> 00:13:08,940
But now we can make this button work

263
00:13:08,940 --> 00:13:12,310
to send the request to our add item controller action

264
00:13:12,310 --> 00:13:16,233
so that we are able to add items and then update that dom.

