WEBVTT

1
00:00:01.180 --> 00:00:03.480
<v Instructor>So in this lecture, we're gonna fix</v>

2
00:00:03.480 --> 00:00:06.730
the request 404 error that we saw happening

3
00:00:06.730 --> 00:00:08.093
in the last lecture.

4
00:00:09.910 --> 00:00:13.090
And so as we saw in the last video, the problem here

5
00:00:13.090 --> 00:00:17.490
is that during the fetch, there was a 404 error,

6
00:00:17.490 --> 00:00:21.080
which is because our API couldn't find any country

7
00:00:21.080 --> 00:00:23.060
with this name.

8
00:00:23.060 --> 00:00:24.770
But still, even though there

9
00:00:24.770 --> 00:00:28.320
was obviously a big problem with this request,

10
00:00:28.320 --> 00:00:32.770
the fetch function still did not reject in this case,

11
00:00:32.770 --> 00:00:34.800
and by the way, many people,

12
00:00:34.800 --> 00:00:38.200
and that includes myself think that in this case,

13
00:00:38.200 --> 00:00:41.820
the promise should actually be rejected right away,

14
00:00:41.820 --> 00:00:43.880
but again, it just doesn't,

15
00:00:43.880 --> 00:00:45.823
and so we will have to do it manually.

16
00:00:47.660 --> 00:00:52.160
So to see what happens here, let's go back

17
00:00:52.160 --> 00:00:57.160
to this first then handler here, which gets access

18
00:00:57.480 --> 00:00:59.143
to the response immediately.

19
00:01:00.010 --> 00:01:01.543
So without even the data.

20
00:01:03.020 --> 00:01:05.460
So here, I'm adding back a block,

21
00:01:05.460 --> 00:01:07.903
and let's take a look at the response here.

22
00:01:08.870 --> 00:01:11.750
And also, since we added back the block,

23
00:01:11.750 --> 00:01:14.683
we now need to return this explicitly.

24
00:01:15.640 --> 00:01:18.320
So again, for now, we are just taking a look

25
00:01:18.320 --> 00:01:20.093
at the response object here.

26
00:01:21.280 --> 00:01:23.100
And so here it is,

27
00:01:23.100 --> 00:01:25.733
and so right here, you can see

28
00:01:25.733 --> 00:01:29.110
that the Ok property is set to false.

29
00:01:29.110 --> 00:01:30.840
And so the reason for that,

30
00:01:30.840 --> 00:01:32.703
is, of course, the status code 404.

31
00:01:34.270 --> 00:01:37.310
Now, when the request goes well,

32
00:01:37.310 --> 00:01:39.910
and so that's what's gonna happen when I click here.

33
00:01:41.940 --> 00:01:46.070
So then if we take a look at the response, Ok is true,

34
00:01:46.070 --> 00:01:48.960
and that's because status is 200.

35
00:01:48.960 --> 00:01:51.883
And so 200 literally stands for Ok.

36
00:01:55.410 --> 00:01:57.140
So we can now use the fact

37
00:01:57.140 --> 00:02:01.102
that this response has the Ok property set to false

38
00:02:01.102 --> 00:02:03.330
to basically reject the promise,

39
00:02:03.330 --> 00:02:07.510
or selves manually, now, right,

40
00:02:07.510 --> 00:02:11.050
so we can do that by creating a new error.

41
00:02:11.050 --> 00:02:16.050
So we can say, if there is no response, dot Ok,

42
00:02:17.310 --> 00:02:21.130
or in other words, if response dot Ok is false,

43
00:02:21.130 --> 00:02:26.130
then we right, throw new error,

44
00:02:26.252 --> 00:02:29.653
and then here we can define an error message.

45
00:02:31.250 --> 00:02:34.230
So let's write a very logical message here,

46
00:02:34.230 --> 00:02:37.880
which is country not found.

47
00:02:37.880 --> 00:02:41.370
So this is the real error message that we want to see here,

48
00:02:41.370 --> 00:02:43.730
and of course, not this one here

49
00:02:43.730 --> 00:02:47.661
with cannot read property of undefined.

50
00:02:47.661 --> 00:02:51.700
And here, we can then also take the status code,

51
00:02:51.700 --> 00:02:53.173
and display it as well.

52
00:02:55.530 --> 00:02:59.040
So this 404, in this case, let's just wrap it here

53
00:02:59.040 --> 00:03:03.640
into parenthesis, and Ok.

54
00:03:03.640 --> 00:03:06.860
So this is something that we never did before.

55
00:03:06.860 --> 00:03:08.863
So let's analyze what happens here.

56
00:03:09.820 --> 00:03:11.516
So we create the new error

57
00:03:11.516 --> 00:03:15.890
by using again, this constructor function, basically,

58
00:03:15.890 --> 00:03:18.540
and then we pass in a message, which is gonna be

59
00:03:18.540 --> 00:03:22.550
the error message, then we use the throw keyword here,

60
00:03:22.550 --> 00:03:25.990
which will immediately terminate the current function.

61
00:03:25.990 --> 00:03:28.850
So just like return does it.

62
00:03:28.850 --> 00:03:30.670
Now the effect of creating,

63
00:03:30.670 --> 00:03:34.290
and throwing an error in any of these then methods

64
00:03:34.290 --> 00:03:37.770
is that the promise will immediately reject.

65
00:03:37.770 --> 00:03:40.310
So basically, the promise returned

66
00:03:40.310 --> 00:03:44.097
by this then handler here will be a rejected promise.

67
00:03:44.097 --> 00:03:47.026
And that rejection will then propagate all the way down

68
00:03:47.026 --> 00:03:51.417
to the catch handler, which we already have set up here.

69
00:03:51.417 --> 00:03:55.200
And so now, if we will try to reload this,

70
00:03:55.200 --> 00:03:56.600
and actually, let's do that.

71
00:03:57.830 --> 00:04:01.230
So now this error message that we created here,

72
00:04:01.230 --> 00:04:04.300
so that's country not found 404.

73
00:04:04.300 --> 00:04:07.880
So exactly this, this is exactly the rejection

74
00:04:07.880 --> 00:04:11.530
that we created here by creating this new error.

75
00:04:11.530 --> 00:04:14.950
All right, so again, any error that happens

76
00:04:14.950 --> 00:04:16.985
in any of the callback functions here,

77
00:04:16.985 --> 00:04:20.550
so in any then handler, will immediately terminate

78
00:04:20.550 --> 00:04:23.170
that then handler and will propagate down

79
00:04:23.170 --> 00:04:26.630
to the catch method here.

80
00:04:26.630 --> 00:04:28.737
And then in there, we handle that error,

81
00:04:28.737 --> 00:04:31.167
and so therefore, that's why we then see

82
00:04:31.167 --> 00:04:32.653
the error here displayed.

83
00:04:33.820 --> 00:04:37.009
So that error dot message is exactly that message

84
00:04:37.009 --> 00:04:39.708
that we pass into the error here.

85
00:04:39.708 --> 00:04:43.604
And in fact, the same is true for any other error.

86
00:04:43.604 --> 00:04:46.250
So before we had this,

87
00:04:46.250 --> 00:04:49.830
the error that we saw was this one here,

88
00:04:49.830 --> 00:04:51.340
and that's because somewhere

89
00:04:51.340 --> 00:04:54.257
in the render country function, we are trying to read

90
00:04:54.257 --> 00:04:57.295
the flag from the data that we received,

91
00:04:57.295 --> 00:05:01.710
but the data that we received did not contain this flag.

92
00:05:01.710 --> 00:05:03.589
And so therefore it created this error,

93
00:05:03.589 --> 00:05:07.748
and then that error caused the rejection of the promise,

94
00:05:07.748 --> 00:05:12.748
which was then one more time handled down here, okay.

95
00:05:12.836 --> 00:05:17.836
So again, any error will cause any promise to reject,

96
00:05:18.040 --> 00:05:20.719
but here, we are simply creating our own error

97
00:05:20.719 --> 00:05:24.140
to basically reject the promise on purpose,

98
00:05:24.140 --> 00:05:25.540
so that we can then handle

99
00:05:25.540 --> 00:05:27.742
that error down here in the chain,

100
00:05:27.742 --> 00:05:31.240
so in this catch method, all right.

101
00:05:31.240 --> 00:05:32.874
But now, you might be wondering,

102
00:05:32.874 --> 00:05:36.650
why should we even bother handle all these errors?

103
00:05:36.650 --> 00:05:40.460
Isn't that just a bunch of work and a waste of time?

104
00:05:40.460 --> 00:05:44.240
Well, first, handling these errors is the only way

105
00:05:44.240 --> 00:05:47.902
in which we can actually display an error message like this

106
00:05:47.902 --> 00:05:50.380
on the screen for the user,

107
00:05:50.380 --> 00:05:54.050
but even more important, it's just a really bad practice

108
00:05:54.050 --> 00:05:57.140
to leave these rejected promises,

109
00:05:57.140 --> 00:05:59.790
hanging around without handling them.

110
00:05:59.790 --> 00:06:03.310
So don't do that, always use catch,

111
00:06:03.310 --> 00:06:07.013
and if necessary, you can also use finally, okay.

112
00:06:08.900 --> 00:06:13.780
And now, again, what if there

113
00:06:13.780 --> 00:06:16.363
was no error here in this promise?

114
00:06:17.770 --> 00:06:20.810
So if we got no problem in this one here,

115
00:06:20.810 --> 00:06:24.186
but then we get a problem in the second fetch.

116
00:06:24.186 --> 00:06:28.520
So let's say that, we don't do this,

117
00:06:28.520 --> 00:06:30.130
and so we have a reasonable country,

118
00:06:30.130 --> 00:06:32.766
which is Portugal when we click on the button,

119
00:06:32.766 --> 00:06:35.963
but then here, let's say that the neighbor is not this one,

120
00:06:37.030 --> 00:06:42.030
but this country code, which I'm sure does not exist.

121
00:06:44.320 --> 00:06:46.470
And so now there is gonna be a rejection

122
00:06:46.470 --> 00:06:49.483
in this promise, right.

123
00:06:51.970 --> 00:06:53.800
So we get another error here.

124
00:06:53.800 --> 00:06:58.600
In this case, it's a 400 error, which means something else,

125
00:06:58.600 --> 00:07:02.350
but in any case, the error is not handled.

126
00:07:02.350 --> 00:07:03.890
So we now need to go ahead,

127
00:07:03.890 --> 00:07:08.263
and copy this code here, also into this then handler.

128
00:07:09.140 --> 00:07:10.921
Let's actually do that, even though we know

129
00:07:10.921 --> 00:07:15.423
it's a bad practice, and we need to fix this later.

130
00:07:19.420 --> 00:07:24.420
Okay, and so now we get the error message that we want.

131
00:07:26.070 --> 00:07:28.240
So again, country not found,

132
00:07:28.240 --> 00:07:30.720
and this time with the code 400.

133
00:07:30.720 --> 00:07:33.883
But now, of course, we have all this duplicate code here.

134
00:07:34.880 --> 00:07:37.530
So we shouldn't have this here.

135
00:07:37.530 --> 00:07:41.510
And in fact, even all of this is kind of repetitive.

136
00:07:41.510 --> 00:07:44.000
It's really, if you think about it

137
00:07:44.000 --> 00:07:46.281
the same code as this one.

138
00:07:46.281 --> 00:07:49.010
And so now, I think that it's a good time

139
00:07:49.010 --> 00:07:53.070
to actually create ourselves a really nice helper function.

140
00:07:53.070 --> 00:07:55.270
And this helper function will wrap up

141
00:07:55.270 --> 00:07:57.110
the fetch the error handling,

142
00:07:57.110 --> 00:07:59.891
and also the conversion to JSON,

143
00:07:59.891 --> 00:08:03.560
because in my opinion, it's really a bit cumbersome

144
00:08:03.560 --> 00:08:06.343
to having to do all these steps all the time.

145
00:08:07.450 --> 00:08:10.730
So having the fetch, and then having to convert

146
00:08:10.730 --> 00:08:12.212
that response to JSON,

147
00:08:12.212 --> 00:08:16.870
and only then being able to handle it, right.

148
00:08:16.870 --> 00:08:20.460
So instead, we will basically encapsulate all of this here

149
00:08:20.460 --> 00:08:23.706
into one nice function, so let's do that,

150
00:08:23.706 --> 00:08:26.343
and I'm gonna call it getJSON.

151
00:08:29.360 --> 00:08:31.930
So basically, because it gets data,

152
00:08:31.930 --> 00:08:35.332
and it immediately converts to JSON.

153
00:08:35.332 --> 00:08:38.123
Now, what do we need here as parameters?

154
00:08:38.980 --> 00:08:41.670
Well, for sure, we need the URL,

155
00:08:41.670 --> 00:08:44.543
and so for now, that's okay, here.

156
00:08:46.090 --> 00:08:51.053
So let's get, or actually, we can just write it.

157
00:08:52.150 --> 00:08:54.370
So what we want here is fetch,

158
00:08:54.370 --> 00:08:57.820
and then the URL that we pass into the function,

159
00:08:57.820 --> 00:09:02.220
and then on that we want to call then,

160
00:09:02.220 --> 00:09:04.453
and then basically with all of this.

161
00:09:06.370 --> 00:09:08.523
So let's grab it here.

162
00:09:12.180 --> 00:09:16.520
And that, of course, we are missing

163
00:09:18.650 --> 00:09:20.353
the callback function itself here,

164
00:09:23.640 --> 00:09:26.733
so that should end somewhere here,

165
00:09:27.950 --> 00:09:31.263
and, well, apparently, it doesn't.

166
00:09:34.610 --> 00:09:39.480
Maybe like this, and yes, that's correct.

167
00:09:39.480 --> 00:09:41.170
All right, now in order

168
00:09:41.170 --> 00:09:44.650
to actually make this function her really generic,

169
00:09:44.650 --> 00:09:47.647
we do not want to hard code the error message,

170
00:09:47.647 --> 00:09:51.120
but instead, we want to pass the message in.

171
00:09:51.120 --> 00:09:53.900
So let's say error message,

172
00:09:53.900 --> 00:09:56.033
and we can set a nice default value.

173
00:09:57.470 --> 00:10:01.320
So let's say something went wrong,

174
00:10:01.320 --> 00:10:03.580
which again is very generic,

175
00:10:03.580 --> 00:10:07.030
and so here, inside of this, we then want

176
00:10:09.560 --> 00:10:12.060
the error message that we passed in,

177
00:10:12.060 --> 00:10:16.010
and along with response dot status.

178
00:10:16.010 --> 00:10:20.941
Okay, and now all we need to do is to return all of this.

179
00:10:20.941 --> 00:10:22.430
And so like this,

180
00:10:22.430 --> 00:10:26.720
this getJSON function will actually return a promise.

181
00:10:26.720 --> 00:10:29.585
And so this is then just like any other promise

182
00:10:29.585 --> 00:10:32.460
that we can call here in our chain,

183
00:10:32.460 --> 00:10:35.233
and basically replace all of this.

184
00:10:36.740 --> 00:10:41.563
So just so we can keep this code, I'm gonna copy it.

185
00:10:42.479 --> 00:10:46.680
And so you can then keep this code here,

186
00:10:46.680 --> 00:10:50.480
basically as a reference for when you need

187
00:10:50.480 --> 00:10:53.770
to study it again, okay.

188
00:10:53.770 --> 00:10:57.300
But again, I will now go ahead and take everything

189
00:10:57.300 --> 00:11:01.247
that we just nicely encapsulated into our getJSON function,

190
00:11:01.247 --> 00:11:03.313
and simply replace this.

191
00:11:05.510 --> 00:11:10.510
So getJSON, and then the URL is this one,

192
00:11:14.260 --> 00:11:18.533
and the error message is country not found, now, right.

193
00:11:22.840 --> 00:11:25.603
And so now, we can take away all of this.

194
00:11:27.590 --> 00:11:30.080
So this is already in our get JSON function,

195
00:11:30.080 --> 00:11:32.363
and so we don't need this.

196
00:11:34.440 --> 00:11:37.940
All right, and now the same down here.

197
00:11:37.940 --> 00:11:40.800
Instead of fetch, we can get JSON,

198
00:11:40.800 --> 00:11:45.440
and then we don't need this done here.

199
00:11:45.440 --> 00:11:49.723
And again, the error message is country not found.

200
00:11:53.750 --> 00:11:57.923
Okay, and so let's get rid of this, now, right.

201
00:12:02.430 --> 00:12:04.041
So let's check here,

202
00:12:04.041 --> 00:12:07.980
and indeed, we get, again, country not found

203
00:12:07.980 --> 00:12:10.823
with code 400 because of this one.

204
00:12:13.200 --> 00:12:15.010
So that's working great,

205
00:12:15.010 --> 00:12:16.460
but there's still one more thing

206
00:12:16.460 --> 00:12:19.650
that we need to do, which is to handle the fact

207
00:12:19.650 --> 00:12:22.550
that sometimes there might be no neighbor.

208
00:12:22.550 --> 00:12:24.570
So right now, what we're doing here when there

209
00:12:24.570 --> 00:12:27.544
is no neighbor, is to simply return,

210
00:12:27.544 --> 00:12:31.460
but as I mentioned before, that doesn't really do anything.

211
00:12:31.460 --> 00:12:36.460
So let me just try here, a country that has no neighbors.

212
00:12:36.694 --> 00:12:41.260
So let's say Australia, because that is an island,

213
00:12:41.260 --> 00:12:45.465
and so here again, we get cannot read property flag

214
00:12:45.465 --> 00:12:48.515
of undefined, and so that is happening,

215
00:12:48.515 --> 00:12:52.593
because it is trying to render a country that doesn't exist.

216
00:12:55.080 --> 00:12:58.951
Okay, so again, it's because of this neighbor,

217
00:12:58.951 --> 00:13:03.390
and just to make sure, to illustrate my point here,

218
00:13:03.390 --> 00:13:06.820
you see that the neighbor is indeed undefined.

219
00:13:06.820 --> 00:13:08.400
And so what we want to do here

220
00:13:08.400 --> 00:13:11.815
is to simply just like before, throw a new error

221
00:13:11.815 --> 00:13:14.103
that will then get caught down here

222
00:13:14.103 --> 00:13:17.593
in our catch handler, right.

223
00:13:20.390 --> 00:13:25.390
So throw new error, no neighbor, found,

224
00:13:29.180 --> 00:13:31.860
and that's a lot better.

225
00:13:31.860 --> 00:13:34.680
So now, this is a real error message

226
00:13:34.680 --> 00:13:37.570
that actually makes sense to the user.

227
00:13:37.570 --> 00:13:39.976
Of course, this could be all a bit better,

228
00:13:39.976 --> 00:13:43.080
but this is just a demonstration anyway,

229
00:13:43.080 --> 00:13:43.913
but I think that

230
00:13:43.913 --> 00:13:47.660
it nicely demonstrate how we can create a real error message

231
00:13:47.660 --> 00:13:49.860
that does actually make sense.

232
00:13:49.860 --> 00:13:51.860
And again, that is super important

233
00:13:51.860 --> 00:13:54.980
for any user interface that you're building,

234
00:13:54.980 --> 00:13:58.710
because in web applications like this very small one,

235
00:13:58.710 --> 00:14:01.770
errors will happen, that is just guaranteed,

236
00:14:01.770 --> 00:14:04.200
and so your application needs to be ready,

237
00:14:04.200 --> 00:14:06.825
and needs to be prepared for that.

238
00:14:06.825 --> 00:14:10.930
All right, so let's now quickly recap here.

239
00:14:10.930 --> 00:14:13.786
And I think that the big takeaway from this lecture

240
00:14:13.786 --> 00:14:17.124
is that whenever we want to create some error

241
00:14:17.124 --> 00:14:19.430
that we want to handle down here,

242
00:14:19.430 --> 00:14:22.833
in the catch handler, all we need to do is to throw,

243
00:14:22.833 --> 00:14:26.990
and create a new error, just like we did here.

244
00:14:26.990 --> 00:14:30.260
And of course, we can do that for multiple reasons.

245
00:14:30.260 --> 00:14:32.660
So in this case, here, we did it simply

246
00:14:32.660 --> 00:14:36.520
because in the situation, no neighbor can be found.

247
00:14:36.520 --> 00:14:39.750
And so that is a good reason to display an error message

248
00:14:39.750 --> 00:14:41.097
on the user interface,

249
00:14:41.097 --> 00:14:44.983
and since we do that down here in our error handler,

250
00:14:46.230 --> 00:14:50.080
the best way of doing that is to indeed throw an error.

251
00:14:50.080 --> 00:14:51.472
And remember that this works,

252
00:14:51.472 --> 00:14:55.760
because throwing an error inside of this callback function

253
00:14:55.760 --> 00:15:00.120
of this then method will immediately reject this promise.

254
00:15:00.120 --> 00:15:03.190
And so then that rejected promise will travel down

255
00:15:03.190 --> 00:15:07.880
the chain until it is eventually caught somewhere.

256
00:15:07.880 --> 00:15:10.608
So again, in this case, it is right here

257
00:15:10.608 --> 00:15:12.980
in this catch handler.

258
00:15:12.980 --> 00:15:15.700
So when working with real applications

259
00:15:15.700 --> 00:15:17.760
in the real world, really make sure

260
00:15:17.760 --> 00:15:19.670
to keep this technique in mind,

261
00:15:19.670 --> 00:15:21.483
because it's really important.

