Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,110 --> 00:00:02,910
So, this is part two
2
00:00:02,910 --> 00:00:05,230
of calculating the review statistics.
3
00:00:05,230 --> 00:00:08,873
This time, for when a review is updated or deleted.
4
00:00:10,780 --> 00:00:13,310
And this part is actually a bit harder
5
00:00:13,310 --> 00:00:15,450
because, keep in mind that a review
6
00:00:15,450 --> 00:00:17,730
is updated or deleted using
7
00:00:19,829 --> 00:00:21,246
findByIdAndUpdate
8
00:00:25,490 --> 00:00:28,277
or also findByIdAndDelete, right?
9
00:00:33,540 --> 00:00:37,020
So for these, we actually do not have document middleware,
10
00:00:37,020 --> 00:00:39,830
but only query middleware, okay.
11
00:00:39,830 --> 00:00:42,630
And so in the query, we actually don't have direct access
12
00:00:42,630 --> 00:00:46,140
to the document in order to then do something similar
13
00:00:46,140 --> 00:00:48,300
to this, okay.
14
00:00:48,300 --> 00:00:51,380
Because, remember, we need access to the current review,
15
00:00:51,380 --> 00:00:54,130
so that from there, we can extract the tour ID,
16
00:00:54,130 --> 00:00:58,030
and then calculate the statistics from there, right,
17
00:00:58,030 --> 00:01:00,130
but again, for these hooks here,
18
00:01:00,130 --> 00:01:02,830
we only have query middleware, okay.
19
00:01:02,830 --> 00:01:04,890
But let me now show you a nice trick
20
00:01:04,890 --> 00:01:07,610
to actually go around this limitation.
21
00:01:07,610 --> 00:01:10,040
So, we're going to implement a pre-middleware
22
00:01:10,040 --> 00:01:14,073
for these hooks, for these events basically.
23
00:01:15,860 --> 00:01:19,730
So pre, and then again I'm going to use
24
00:01:19,730 --> 00:01:22,870
a regular expression for a string starting
25
00:01:22,870 --> 00:01:25,457
with findOneAnd and that's it.
26
00:01:28,641 --> 00:01:30,410
And so this one is then going to work
27
00:01:30,410 --> 00:01:33,970
for findOneAndUpdate, and findOneAndDelete
28
00:01:34,830 --> 00:01:37,150
because, remember that behind the scenes,
29
00:01:37,150 --> 00:01:40,480
findByIdAndUpdate is only just a shorthand
30
00:01:40,480 --> 00:01:44,750
for findOneAndUpdate with the current ID, right.
31
00:01:44,750 --> 00:01:48,530
So here, we actually need to use the findOneAndDelete
32
00:01:48,530 --> 00:01:52,833
and findOneAndUpdate middleware hooks, all right.
33
00:01:55,500 --> 00:01:59,970
So, function, and it gets the next keyword
34
00:01:59,970 --> 00:02:02,420
because it's pre-middleware.
35
00:02:02,420 --> 00:02:05,310
So, remember that the goal is to get access
36
00:02:05,310 --> 00:02:07,990
to the current review document, okay,
37
00:02:07,990 --> 00:02:11,280
but here the, this keyword is the current query.
38
00:02:11,280 --> 00:02:13,650
Now, how are we going to go around this?
39
00:02:13,650 --> 00:02:16,150
Well, we can basically execute a query,
40
00:02:16,150 --> 00:02:18,200
and then that will give us the document
41
00:02:18,200 --> 00:02:20,040
that's currently being processed.
42
00:02:20,040 --> 00:02:22,650
So in order to do that, we can use findOne.
43
00:02:25,590 --> 00:02:26,590
And that's it.
44
00:02:26,590 --> 00:02:29,740
So then all we need to do is await this query
45
00:02:29,740 --> 00:02:31,090
and then save it somewhere.
46
00:02:34,140 --> 00:02:38,850
So let's call it r, which is gonna stand for review, okay.
47
00:02:38,850 --> 00:02:40,763
Then save it as async.
48
00:02:42,650 --> 00:02:43,773
And, that's it.
49
00:02:45,000 --> 00:02:47,830
And just to make sure that this works here,
50
00:02:47,830 --> 00:02:52,340
let's for now just log this to the console, okay.
51
00:02:52,340 --> 00:02:55,080
So without doing any calculations,
52
00:02:55,080 --> 00:02:56,760
all we're really interested in
53
00:02:56,760 --> 00:02:59,960
is to see if this nice trick here works.
54
00:02:59,960 --> 00:03:02,410
So basically, the trick of going around
55
00:03:02,410 --> 00:03:04,070
that in a query midddleware,
56
00:03:04,070 --> 00:03:05,853
we only have access to the query.
57
00:03:06,890 --> 00:03:09,850
So again, we need to get access to the document,
58
00:03:09,850 --> 00:03:13,210
and so we basically execute this query
59
00:03:13,210 --> 00:03:14,463
by using findOne.
60
00:03:15,620 --> 00:03:20,603
All right, so let's update a review,
61
00:03:22,570 --> 00:03:26,313
and so let's actually update the last one that we did,
62
00:03:31,310 --> 00:03:33,050
all right, and the rating,
63
00:03:33,050 --> 00:03:35,010
now let's actually set it to four.
64
00:03:35,010 --> 00:03:37,080
So it was five before
65
00:03:38,130 --> 00:03:42,023
and so now we are changing it to four.
66
00:03:43,040 --> 00:03:44,083
So it sent that,
67
00:03:46,900 --> 00:03:50,620
and here is the review.
68
00:03:50,620 --> 00:03:53,140
Now of course, the rating is still set to five
69
00:03:53,140 --> 00:03:56,130
at this point, because this findOne here
70
00:03:56,130 --> 00:03:58,850
really gets the document from the database,
71
00:03:58,850 --> 00:04:01,660
and so at this point of time, in pre,
72
00:04:01,660 --> 00:04:04,900
it still didn't persist any changes to the database,
73
00:04:04,900 --> 00:04:06,540
and so it was five before,
74
00:04:06,540 --> 00:04:08,990
and so now it's still gonna be five.
75
00:04:08,990 --> 00:04:10,460
But that doesn't really matter here
76
00:04:10,460 --> 00:04:13,750
because all we are interested in is this ID.
77
00:04:13,750 --> 00:04:16,579
Actually, this tour ID, right,
78
00:04:16,579 --> 00:04:18,350
because that is what we're gonna need
79
00:04:18,350 --> 00:04:21,220
in order to calculate the average ratings.
80
00:04:21,220 --> 00:04:24,363
Okay, and so now, let's actually use that function.
81
00:04:25,240 --> 00:04:27,850
Okay, now, let's think about this
82
00:04:27,850 --> 00:04:32,190
because if we were to use this calcAverageRatings function
83
00:04:32,190 --> 00:04:33,850
at this point in time,
84
00:04:33,850 --> 00:04:36,100
then we would calculate the statistics
85
00:04:36,100 --> 00:04:39,490
using the non-updated data, okay.
86
00:04:39,490 --> 00:04:42,390
And so that's the exact same reason why up here,
87
00:04:42,390 --> 00:04:45,400
we also needed to use post and not pre,
88
00:04:45,400 --> 00:04:48,650
okay, because only after the document is already saved
89
00:04:48,650 --> 00:04:50,620
to the database it makes sense
90
00:04:50,620 --> 00:04:52,850
to then calculate the ratings.
91
00:04:52,850 --> 00:04:55,570
And so here, it's the exact same thing,
92
00:04:55,570 --> 00:04:58,650
with the big difference that we cannot simply change
93
00:04:58,650 --> 00:05:00,533
this pre to post.
94
00:05:01,390 --> 00:05:04,500
So we cannot do that because at this point in time
95
00:05:04,500 --> 00:05:07,260
we no longer have access to the query
96
00:05:07,260 --> 00:05:10,410
because the query has already executed, right,
97
00:05:10,410 --> 00:05:11,500
and so without the query,
98
00:05:11,500 --> 00:05:13,670
we cannot save the review document,
99
00:05:13,670 --> 00:05:16,410
and we can then not run this function.
100
00:05:16,410 --> 00:05:20,360
So, this is really confusing, I understand,
101
00:05:20,360 --> 00:05:23,710
but I really decided to create this lecture in this way
102
00:05:23,710 --> 00:05:25,790
because, well, it's really the only solution
103
00:05:25,790 --> 00:05:28,730
around this problem, and it's a really great exercise
104
00:05:28,730 --> 00:05:32,240
for you to basically understand this Hello Experience.
105
00:05:32,240 --> 00:05:35,833
So, the solution for this is to now use post,
106
00:05:37,520 --> 00:05:40,690
so, reviewSchema, then basically the same,
107
00:05:40,690 --> 00:05:44,460
so let's just, actually let's just copy all of this,
108
00:05:44,460 --> 00:05:47,640
make our lives a bit easier,
109
00:05:47,640 --> 00:05:50,033
get rid of this, and get rid of the next.
110
00:05:51,850 --> 00:05:54,320
Here, we also need to call next, okay,
111
00:05:54,320 --> 00:05:58,170
but then we do it post, okay.
112
00:05:58,170 --> 00:05:59,730
And so now this point in time,
113
00:05:59,730 --> 00:06:01,840
so after the query has already finished,
114
00:06:01,840 --> 00:06:04,700
and so therefore the review has been updated,
115
00:06:04,700 --> 00:06:06,290
this is a perfect point in time
116
00:06:06,290 --> 00:06:08,283
where we can then call this function.
117
00:06:09,510 --> 00:06:12,720
So, calculate average ratings.
118
00:06:12,720 --> 00:06:15,930
But where do we now get the tour ID from?
119
00:06:15,930 --> 00:06:17,860
Well, we're gonna have to use a trick
120
00:06:17,860 --> 00:06:21,260
which is basically to pass data from the pre-middleware
121
00:06:21,260 --> 00:06:23,000
to the post middleware.
122
00:06:23,000 --> 00:06:26,690
And so instead of saving this document to a simple variable,
123
00:06:26,690 --> 00:06:30,403
we're gonna save it to this.r.
124
00:06:31,750 --> 00:06:35,773
So basically, we create a property on this variable.
125
00:06:36,700 --> 00:06:40,390
Okay, and so now here, we still have access to that.
126
00:06:40,390 --> 00:06:45,350
And so now, we can say this.r, which remember is the review,
127
00:06:45,350 --> 00:06:47,603
and then .tour.
128
00:06:49,220 --> 00:06:53,300
So, this is again quite confusing,
129
00:06:53,300 --> 00:06:56,850
but again also quite fun once you understand
130
00:06:56,850 --> 00:06:58,873
how this really works, okay.
131
00:06:59,800 --> 00:07:03,200
Now, again, we need something like this here
132
00:07:03,200 --> 00:07:06,320
in order to actually call this function here
133
00:07:06,320 --> 00:07:08,460
because remember that this in fact
134
00:07:08,460 --> 00:07:12,570
is a static method, and so we need to call it on the model.
135
00:07:12,570 --> 00:07:15,500
Now where is this model in this case?
136
00:07:15,500 --> 00:07:20,500
Well, it's at this.r,
137
00:07:20,848 --> 00:07:22,550
which is in this case, equivalent
138
00:07:22,550 --> 00:07:25,113
to this this here in this middleware,
139
00:07:26,427 --> 00:07:29,217
.constructor.calcAverageRatings.
140
00:07:31,860 --> 00:07:35,403
Woo, that looks quite overwhelming, doesn't it?
141
00:07:36,600 --> 00:07:38,100
Of course, we have to await it,
142
00:07:38,100 --> 00:07:42,600
so that's why we declared this as async, okay.
143
00:07:42,600 --> 00:07:46,210
So, again, we basically used this way here
144
00:07:46,210 --> 00:07:48,530
of passing the data from the pre-middleware
145
00:07:48,530 --> 00:07:50,930
to the post middleware, and so then here
146
00:07:50,930 --> 00:07:55,060
we retrieved the review document from this variable.
147
00:07:55,060 --> 00:07:59,970
Okay, and again, we did have to do it in this way
148
00:07:59,970 --> 00:08:01,317
because at this point in time here,
149
00:08:01,317 --> 00:08:03,550
the query was already executed,
150
00:08:03,550 --> 00:08:06,783
and so we could not do this here.
151
00:08:11,950 --> 00:08:16,753
And let's actually write that down; does NOT work here,
152
00:08:19,690 --> 00:08:21,253
query has already executed.
153
00:08:22,610 --> 00:08:24,130
Great, and with this,
154
00:08:24,130 --> 00:08:27,103
we should actually now be ready to test this.
155
00:08:28,100 --> 00:08:32,850
So let's go ahead and update this one here once more,
156
00:08:32,850 --> 00:08:37,493
and set it to a rating of one, all right.
157
00:08:39,159 --> 00:08:41,059
Let's now let's take a look here,
158
00:08:41,059 --> 00:08:44,020
until you see that the number of ratings is still five,
159
00:08:44,020 --> 00:08:46,620
but the average is now only three,
160
00:08:46,620 --> 00:08:49,220
and now the question is if this really updated
161
00:08:49,220 --> 00:08:50,593
also on the tour,
162
00:08:53,740 --> 00:08:58,150
and, yep, indeed, it did.
163
00:08:58,150 --> 00:09:02,040
So, five ratings with an average of three.
164
00:09:02,040 --> 00:09:06,220
Great, let's now update another one.
165
00:09:06,220 --> 00:09:09,543
So, in order to that, let's get all our reviews,
166
00:09:11,570 --> 00:09:14,280
and actually we do not want all of them,
167
00:09:14,280 --> 00:09:16,201
but only the last one.
168
00:09:16,201 --> 00:09:18,730
And here I still I have this filter,
169
00:09:18,730 --> 00:09:20,253
so I should get rid of that,
170
00:09:21,650 --> 00:09:26,650
so we get all 65 results, so all of these reviews,
171
00:09:26,980 --> 00:09:29,280
but we only want the last ones,
172
00:09:29,280 --> 00:09:31,073
so the ones that we just created.
173
00:09:32,820 --> 00:09:34,160
So let's update...
174
00:09:37,570 --> 00:09:42,090
I'm not sure, because actually they're not in order here.
175
00:09:42,090 --> 00:09:47,090
Let's, okay, so here we have the most recent ones.
176
00:09:47,490 --> 00:09:50,963
So let me now update this one here, to let's say, four,
177
00:09:56,540 --> 00:09:59,410
just as a final test, and so that should
178
00:09:59,410 --> 00:10:01,173
bring the average up a little bit.
179
00:10:02,490 --> 00:10:04,090
And indeed it did.
180
00:10:04,090 --> 00:10:07,400
So, 3.6 now, and of course, the number is still five
181
00:10:07,400 --> 00:10:10,400
because you didn't add a new review.
182
00:10:10,400 --> 00:10:12,700
So it works great on update,
183
00:10:12,700 --> 00:10:15,463
let's now actually also test it with deleting.
184
00:10:17,470 --> 00:10:21,710
So let's go ahead and delete the review that we just updated
185
00:10:23,350 --> 00:10:26,860
and so now we should be down to only four,
186
00:10:26,860 --> 00:10:28,550
and indeed, here we are.
187
00:10:28,550 --> 00:10:30,100
So now, only four.
188
00:10:30,100 --> 00:10:32,053
And let's actually delete all of them.
189
00:10:35,410 --> 00:10:36,723
So, this one is next.
190
00:10:45,038 --> 00:10:46,180
Ah, here we are.
191
00:10:46,180 --> 00:10:47,303
Then also this one.
192
00:10:53,560 --> 00:10:55,760
So, now we should be down to three only
193
00:10:56,970 --> 00:11:00,350
or, actually, we only just have two left
194
00:11:00,350 --> 00:11:01,893
with an average of four.
195
00:11:05,600 --> 00:11:08,300
So let's see which one we have still left.
196
00:11:08,300 --> 00:11:12,330
So it's this one with three and this one with five.
197
00:11:12,330 --> 00:11:15,203
And so that's why we have this average of four.
198
00:11:19,210 --> 00:11:21,320
So let's get rid of this one
199
00:11:21,320 --> 00:11:25,020
and so now our average should be five, right?
200
00:11:25,020 --> 00:11:26,340
Or actually three
201
00:11:26,340 --> 00:11:29,340
because the only one that's left has three.
202
00:11:29,340 --> 00:11:33,350
And now the final test, deleting the last one,
203
00:11:33,350 --> 00:11:35,993
just to see what's gonna happen once we do that.
204
00:11:41,070 --> 00:11:42,530
And, we get an error here.
205
00:11:42,530 --> 00:11:46,400
So, cannot read property nRating of undefined.
206
00:11:46,400 --> 00:11:50,683
So that's calcAverageRatings at line number 69.
207
00:11:53,280 --> 00:11:54,903
So, don't know what this is.
208
00:11:55,760 --> 00:12:00,440
So, line 69, and so, it's this problem here.
209
00:12:00,440 --> 00:12:03,530
So we're trying to read nRating of undefined.
210
00:12:03,530 --> 00:12:06,420
So stats zero is basically undefined.
211
00:12:06,420 --> 00:12:09,400
And that's because if there are no document
212
00:12:09,400 --> 00:12:11,780
matching this query here basically,
213
00:12:11,780 --> 00:12:13,947
well then we simply get back an empty array.
214
00:12:13,947 --> 00:12:17,100
And so that's actually exactly what we have down here.
215
00:12:17,100 --> 00:12:19,350
So this is the stats array
216
00:12:19,350 --> 00:12:22,630
and so right now it doesn't have any results, okay,
217
00:12:22,630 --> 00:12:25,500
so we should only execute this piece of code here
218
00:12:25,500 --> 00:12:28,653
whenever we actually do have something in the stats array.
219
00:12:29,810 --> 00:12:30,903
So let's do that.
220
00:12:31,760 --> 00:12:36,760
So if stats.length is greater than zero,
221
00:12:40,090 --> 00:12:42,623
well, then do this.
222
00:12:45,450 --> 00:12:48,100
And if not, well, basically that means
223
00:12:48,100 --> 00:12:50,260
that all our reviews are gone,
224
00:12:50,260 --> 00:12:54,280
well then we basically want to go back to the default.
225
00:12:54,280 --> 00:12:58,780
So we're gonna set it then to the quantity of zero
226
00:12:58,780 --> 00:13:02,030
and the average of 4.5, which remember,
227
00:13:02,030 --> 00:13:04,943
is the default when there are no reviews at all.
228
00:13:08,540 --> 00:13:10,823
So let's quickly create a new review,
229
00:13:12,200 --> 00:13:13,150
and it can be this,
230
00:13:15,880 --> 00:13:19,400
all right, so we're back to having one rating,
231
00:13:19,400 --> 00:13:20,780
and now delete it right away,
232
00:13:20,780 --> 00:13:24,963
just to test that piece of code we just wrote,
233
00:13:28,080 --> 00:13:30,310
just to see it here as well,
234
00:13:30,310 --> 00:13:32,573
so one rating, average five.
235
00:13:33,850 --> 00:13:36,113
And now when we delete it,
236
00:13:38,910 --> 00:13:41,790
we no longer get an error.
237
00:13:41,790 --> 00:13:45,630
And on our tour, we are back to zero
238
00:13:45,630 --> 00:13:48,450
and a default of 4.5.
239
00:13:48,450 --> 00:13:51,560
All right, all right, all right, perfect.
240
00:13:51,560 --> 00:13:54,920
So let's again take just a quick second here
241
00:13:54,920 --> 00:13:57,090
to recap what we just did.
242
00:13:57,090 --> 00:13:59,970
So in order to be able to run this function here
243
00:13:59,970 --> 00:14:02,320
also on update and on delete,
244
00:14:02,320 --> 00:14:04,590
we actually need to use the query middleware
245
00:14:04,590 --> 00:14:07,110
that Mongoose gives us for these situations.
246
00:14:07,110 --> 00:14:11,230
Okay, so, we do not have a handy document middleware,
247
00:14:11,230 --> 00:14:13,140
which works, for these functions,
248
00:14:13,140 --> 00:14:15,880
but instead we need to use the query middleware,
249
00:14:15,880 --> 00:14:18,660
and in that one, we do not directly have access
250
00:14:18,660 --> 00:14:20,090
to the current document.
251
00:14:20,090 --> 00:14:21,540
And so we need to go around that
252
00:14:21,540 --> 00:14:24,870
by using this findOne here, and so basically retrieving
253
00:14:24,870 --> 00:14:27,340
the current document from the database.
254
00:14:27,340 --> 00:14:30,450
We then store it on the current query variable,
255
00:14:30,450 --> 00:14:32,950
and so that's this, and by doing that,
256
00:14:32,950 --> 00:14:36,480
we then get access to it in the post middleware.
257
00:14:36,480 --> 00:14:38,610
And it's then only in the post middleware
258
00:14:38,610 --> 00:14:42,500
where we actually calculate the statistics for reviews.
259
00:14:42,500 --> 00:14:44,370
And remember that we do it this way
260
00:14:44,370 --> 00:14:47,380
because if we did it right in this middleware function,
261
00:14:47,380 --> 00:14:50,100
then the underlying data would not have been updated
262
00:14:50,100 --> 00:14:53,150
at that point and so the calculated statistics
263
00:14:53,150 --> 00:14:55,150
would not really be up to date.
264
00:14:55,150 --> 00:14:56,540
And so that's why we used
265
00:14:56,540 --> 00:14:58,963
this two-step process here basically.
266
00:15:00,020 --> 00:15:02,220
Now, let's get rid of this console.log here,
267
00:15:03,130 --> 00:15:06,883
since we're finished now, and also of these statistics.
268
00:15:08,270 --> 00:15:11,390
So, I hope that this was fun to you
269
00:15:11,390 --> 00:15:13,890
and not all too overwhelming.
270
00:15:13,890 --> 00:15:16,390
I designed this exercise specifically
271
00:15:16,390 --> 00:15:19,270
so that we could solve a real world business problem
272
00:15:19,270 --> 00:15:22,150
by using all the tools that Mongoose gives us.
273
00:15:22,150 --> 00:15:24,500
And so, with that, I hope that you learned a bit better
274
00:15:24,500 --> 00:15:26,980
how to work with all these different middlewares
275
00:15:26,980 --> 00:15:29,220
in different situations whenever needed
276
00:15:29,220 --> 00:15:31,640
in a real world situation.
277
00:15:31,640 --> 00:15:35,700
So, great job for finishing this quite challenging lecture
278
00:15:35,700 --> 00:15:39,030
and for still being with me at this point of the course.
279
00:15:39,030 --> 00:15:40,594
It's really good for me to see,
280
00:15:40,594 --> 00:15:43,500
so I'm really happy about that.
281
00:15:43,500 --> 00:15:46,780
But anyway, there's still some more great content coming up
282
00:15:46,780 --> 00:15:48,290
in this section actually,
283
00:15:48,290 --> 00:15:51,723
and so let's now move on together, right to the next video.
22186
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.