1
00:00:03,650 --> 00:00:06,180
In the previous exercise,

2
00:00:06,180 --> 00:00:09,414
we learned about two new aspects of JavaScript,

3
00:00:09,414 --> 00:00:13,155
their support for first class functions and closures.

4
00:00:13,155 --> 00:00:20,250
We also saw how Node handles the asynchronous programming aspect and how Node

5
00:00:20,250 --> 00:00:24,015
supports asynchronous execution of code with

6
00:00:24,015 --> 00:00:28,365
the use of callbacks and also error handling.

7
00:00:28,365 --> 00:00:31,815
Let's look at an example of how we make use of this

8
00:00:31,815 --> 00:00:36,650
within our Node application in this exercise.

9
00:00:36,650 --> 00:00:42,315
Continuing with where we left off in the previous exercise,

10
00:00:42,315 --> 00:00:48,025
now I'm going to go and modify the rectangle Node module,

11
00:00:48,025 --> 00:00:51,670
so that it can take the help of callbacks.

12
00:00:51,670 --> 00:00:55,375
So I'm going to remove these exports here,

13
00:00:55,375 --> 00:00:59,800
and instead, they're going to modify this function.

14
00:00:59,800 --> 00:01:03,190
I'm going to be making use of these two functions a little bit later,

15
00:01:03,190 --> 00:01:05,925
so that's why I'm saving them at the bottom.

16
00:01:05,925 --> 00:01:07,515
So let me keep them aside.

17
00:01:07,515 --> 00:01:11,530
And then I will modify this rectangle module as follows.

18
00:01:11,530 --> 00:01:15,270
So we'll say module.exports.

19
00:01:15,270 --> 00:01:20,025
So we're are using the standard way the module is handled.

20
00:01:20,025 --> 00:01:26,185
And this is going to export this function which takes these three parameters,

21
00:01:26,185 --> 00:01:30,565
x and y and callback.

22
00:01:30,565 --> 00:01:37,300
The callback is a function that is going to be supplied in when this module is called.

23
00:01:37,300 --> 00:01:43,825
So this is the use of the first class functions that we have talked about earlier.

24
00:01:43,825 --> 00:01:46,775
So inside this callback,

25
00:01:46,775 --> 00:01:49,940
so you can see that you're getting two parameters, x and y.

26
00:01:49,940 --> 00:01:51,965
In this case, for the rectangle,

27
00:01:51,965 --> 00:01:55,520
the x and y correspond to the length and breadth of

28
00:01:55,520 --> 00:02:01,550
the rectangle that is being passed in as the two values.

29
00:02:01,550 --> 00:02:05,090
So inside here, we're going to check to see

30
00:02:05,090 --> 00:02:10,300
if x is less than or equal to zero or y is less than or equal to zero.

31
00:02:10,300 --> 00:02:13,255
We have written code like this here.

32
00:02:13,255 --> 00:02:17,630
So I'm just going to copy this code from here

33
00:02:17,630 --> 00:02:23,330
and then bring it over to here and then we'll edit.

34
00:02:23,330 --> 00:02:26,090
So in this case, this is if x is less

35
00:02:26,090 --> 00:02:30,135
than or equal to zero or y is less than or equal to zero.

36
00:02:30,135 --> 00:02:32,810
In this case, what do we do?

37
00:02:32,810 --> 00:02:35,435
In this case, we notice that

38
00:02:35,435 --> 00:02:39,750
the dimensions of the rectangle are less than or equal to zero.

39
00:02:39,750 --> 00:02:43,775
So we have to handle it differently,

40
00:02:43,775 --> 00:02:46,330
and we'll do the else part of it.

41
00:02:46,330 --> 00:02:52,790
The else part where we handle the situation where the rectangle is a valid rectangle.

42
00:02:52,790 --> 00:02:54,245
So in this case,

43
00:02:54,245 --> 00:03:04,580
what we will do is to then use a setTimeout.

44
00:03:04,580 --> 00:03:08,090
So here, I am simulating the fact that whatever

45
00:03:08,090 --> 00:03:11,860
is being done in this rectangle is going to take some time.

46
00:03:11,860 --> 00:03:14,375
So this is the asynchronous processing.

47
00:03:14,375 --> 00:03:18,710
Now, since I don't have a lot of work to do in the background,

48
00:03:18,710 --> 00:03:22,530
so I'm going to simulate that by simply using

49
00:03:22,530 --> 00:03:24,830
the setTimeout function of JavaScript and then

50
00:03:24,830 --> 00:03:28,825
delay before the callback function is called.

51
00:03:28,825 --> 00:03:32,210
So the way I arrange this is as follows.

52
00:03:32,210 --> 00:03:34,270
So inside the setTimeout,

53
00:03:34,270 --> 00:03:40,445
I'm going to call this function there

54
00:03:40,445 --> 00:03:44,855
and arrange a delay of

55
00:03:44,855 --> 00:03:50,570
2,000 milliseconds or two seconds after which this function is going to be called.

56
00:03:50,570 --> 00:03:52,003
So if you recall,

57
00:03:52,003 --> 00:03:54,890
the setTimeout that is supported in JavaScript,

58
00:03:54,890 --> 00:03:58,070
it takes as the first parameter a function and

59
00:03:58,070 --> 00:04:03,450
the second parameter would be the time period for which this is going to be delayed.

60
00:04:03,450 --> 00:04:07,120
So let me indent this in.

61
00:04:07,120 --> 00:04:09,255
Now, I need to fill in this function here.

62
00:04:09,255 --> 00:04:11,915
So I have started out with the arrow function here

63
00:04:11,915 --> 00:04:15,575
which takes no parameters and then when there is called,

64
00:04:15,575 --> 00:04:20,745
I'm going to issue a call to the callback.

65
00:04:20,745 --> 00:04:22,880
This callback is a callback function that is

66
00:04:22,880 --> 00:04:25,760
going to be passed in as the third parameter here.

67
00:04:25,760 --> 00:04:33,440
This callback function, as you noticed, takes two parameters.

68
00:04:33,440 --> 00:04:38,245
The first one is the error and the second one is the return value.

69
00:04:38,245 --> 00:04:40,625
So in this case, since we have an error,

70
00:04:40,625 --> 00:04:44,750
because x is less than or equal to zero and y is less than or equal to zero,

71
00:04:44,750 --> 00:04:50,820
so the first value I'm going to pass in as new error,

72
00:04:50,820 --> 00:05:00,603
and this error is exactly this string that I was using in the console.log then,

73
00:05:00,603 --> 00:05:03,915
and that is what I will pass in as the error here.

74
00:05:03,915 --> 00:05:06,160
Let me now delete that console.log,

75
00:05:06,160 --> 00:05:07,625
I no longer need it.

76
00:05:07,625 --> 00:05:08,890
So for the callback,

77
00:05:08,890 --> 00:05:13,210
I'm going to generate a new error object and then pass this

78
00:05:13,210 --> 00:05:18,850
in as the return value for the callback function, the first parameter.

79
00:05:18,850 --> 00:05:23,770
So I'll say rectangle dimensions should be greater than zero.

80
00:05:23,770 --> 00:05:28,240
So we'll say l,

81
00:05:28,240 --> 00:05:39,000
this is the x and the y value that we got as the input values there.

82
00:05:39,000 --> 00:05:40,650
So that is the callback.

83
00:05:40,650 --> 00:05:43,890
And the second part of this callback,

84
00:05:43,890 --> 00:05:51,290
I'm going to pass in as null because this is going to return an error.

85
00:05:51,290 --> 00:05:54,345
So when you return an error as the first parameter,

86
00:05:54,345 --> 00:05:59,250
the second parameter will be ignored when that callback was just received by

87
00:05:59,250 --> 00:06:06,510
the node module from where we are calling this particular function there.

88
00:06:06,510 --> 00:06:09,085
So, with this arrangement,

89
00:06:09,085 --> 00:06:10,700
so less than zero,

90
00:06:10,700 --> 00:06:18,590
so let me give some space here so that it's properly indented here.

91
00:06:18,590 --> 00:06:21,650
So, the way I am arranging this

92
00:06:21,650 --> 00:06:26,135
here is that if x is less than zero and y is less than zero,

93
00:06:26,135 --> 00:06:30,040
I'm going to callback the callback function that has been passed in,

94
00:06:30,040 --> 00:06:32,424
but the first parameter will pass in in

95
00:06:32,424 --> 00:06:36,307
error because here we notice that there is an error,

96
00:06:36,307 --> 00:06:38,930
and the second parameter will be null.

97
00:06:38,930 --> 00:06:40,940
If this is not the case,

98
00:06:40,940 --> 00:06:44,550
then I'm going to call the same callback,

99
00:06:44,550 --> 00:06:46,910
but with the first parameter.

100
00:06:46,910 --> 00:06:51,800
So let me copy that code in here.

101
00:06:51,800 --> 00:07:05,490
I'm still going to use the setTimeout here.

102
00:07:05,490 --> 00:07:10,727
But that first part is not going to be an error,

103
00:07:10,727 --> 00:07:13,005
instead, the first part,

104
00:07:13,005 --> 00:07:15,235
in this case, there is no error.

105
00:07:15,235 --> 00:07:20,455
So I'm just going to pass back that value as null.

106
00:07:20,455 --> 00:07:22,950
So that means that the error is set to null.

107
00:07:22,950 --> 00:07:26,335
So this is a valid rectangle.

108
00:07:26,335 --> 00:07:29,965
So we can compute the values for the rectangle.

109
00:07:29,965 --> 00:07:35,165
But instead, I'm going to simply pass in

110
00:07:35,165 --> 00:07:40,020
a JavaScript object containing the two functions

111
00:07:40,020 --> 00:07:45,330
as the two values inside this JavaScript object.

112
00:07:45,330 --> 00:07:50,355
So, here I am going to take this two,

113
00:07:50,355 --> 00:07:54,530
the perimeter and the area,

114
00:07:55,250 --> 00:08:05,639
and then these two will be passed in as the two values here,

115
00:08:05,639 --> 00:08:07,807
perimeter and the area.

116
00:08:07,807 --> 00:08:12,740
And these two, since they happen to be a JavaScript object,

117
00:08:12,740 --> 00:08:16,544
so perimeter and area will be

118
00:08:16,544 --> 00:08:22,690
the two properties that I will pass in inside those JavaScript object,

119
00:08:22,690 --> 00:08:25,295
and that is it.

120
00:08:25,295 --> 00:08:28,570
So here, in the second case,

121
00:08:28,570 --> 00:08:32,034
the error is set to null because there is no error,

122
00:08:32,034 --> 00:08:33,190
but the second part,

123
00:08:33,190 --> 00:08:37,715
notice that I am passing in a JavaScript object containing two properties,

124
00:08:37,715 --> 00:08:41,530
perimeter and area, which are two functions here.

125
00:08:41,530 --> 00:08:46,060
So the two functions are the perimeter function and area function.

126
00:08:46,060 --> 00:08:49,390
So this JavaScript object will be passed back as

127
00:08:49,390 --> 00:08:53,705
the return value for the callback here, the second value.

128
00:08:53,705 --> 00:08:56,035
And again, I am going to delay this by

129
00:08:56,035 --> 00:09:02,900
a two second interval before the value will be passed back by this function.

130
00:09:02,900 --> 00:09:07,075
The reason why I'm using the setTimeout is to simulate

131
00:09:07,075 --> 00:09:11,780
a delay before the callback comes in from the other side.

132
00:09:11,780 --> 00:09:15,280
So this sort of represents situations where, for example,

133
00:09:15,280 --> 00:09:18,565
you issue a database call to the database,

134
00:09:18,565 --> 00:09:23,300
and the database needs to be read before the value is passed back to you.

135
00:09:23,300 --> 00:09:25,855
So that is going to take a certain amount of time.

136
00:09:25,855 --> 00:09:32,560
So I'm basically simulating this at this moment by using the setTimeout function here.

137
00:09:32,560 --> 00:09:37,000
Later on, you will see that when we integrate the MongoDB with

138
00:09:37,000 --> 00:09:43,060
our Express in the later exercises,

139
00:09:43,060 --> 00:09:45,580
that delay would have to be simulated,

140
00:09:45,580 --> 00:09:48,670
it'll be automatically caused because of the fact that you need to do

141
00:09:48,670 --> 00:09:54,190
database operations behind the scenes before the data is obtained.

142
00:09:54,190 --> 00:10:00,325
So here, having completed this rectangle modules update,

143
00:10:00,325 --> 00:10:03,135
so here you see that the rectangle module takes in

144
00:10:03,135 --> 00:10:06,830
three parameters as it's a input call here,

145
00:10:06,830 --> 00:10:08,920
x, y and callback.

146
00:10:08,920 --> 00:10:12,445
And so, the callback is the callback function that is being supplied here.

147
00:10:12,445 --> 00:10:16,585
And this callback function will be called inside here,

148
00:10:16,585 --> 00:10:18,685
and when the callback function is called,

149
00:10:18,685 --> 00:10:22,495
either you pass back an error or you pass back

150
00:10:22,495 --> 00:10:28,045
a function that allows you to compute the perimeter and the area of the rectangle.

151
00:10:28,045 --> 00:10:33,835
Now, this pattern of calling in and passing in a callback function

152
00:10:33,835 --> 00:10:40,300
from one Node module and then the second Node module which when it completes,

153
00:10:40,300 --> 00:10:44,800
will pass back the result using the callback function is

154
00:10:44,800 --> 00:10:50,135
exactly the pattern that you will see often repeated in Node applications.

155
00:10:50,135 --> 00:10:52,360
So that's the reason why I'm illustrating it.

156
00:10:52,360 --> 00:10:58,735
Of course, this is a contrived example that I am illustrating here but it shows

157
00:10:58,735 --> 00:11:02,525
all the standard patterns that you will use with node

158
00:11:02,525 --> 00:11:07,065
and callback functions and also the error handling.

159
00:11:07,065 --> 00:11:10,955
Now, we have updated the rectangle module here.

160
00:11:10,955 --> 00:11:16,870
Let's go and fix that index.js file so that it can pass in the callback function and

161
00:11:16,870 --> 00:11:23,770
then handle the return value that is sent back from the rectangle module.

162
00:11:23,770 --> 00:11:26,940
Switching back to index.js,

163
00:11:26,940 --> 00:11:31,270
now we are going to update the index.js file as follows.

164
00:11:31,270 --> 00:11:37,955
I'm going to remove this from the index.js file instead.

165
00:11:37,955 --> 00:11:42,430
Here, what we will end up doing is call

166
00:11:42,430 --> 00:11:49,120
this rectangle module and

167
00:11:49,120 --> 00:11:53,880
then pass in the l and the b as the two parameters.

168
00:11:53,880 --> 00:12:00,300
And the third parameter that I'm going to pass in is that callback function.

169
00:12:00,300 --> 00:12:10,080
So the callback function has two parameters, err and rectangle.

170
00:12:10,080 --> 00:12:15,860
And this callback function is implemented as follows here.

171
00:12:15,860 --> 00:12:19,090
So here, you see that I'm calling

172
00:12:19,090 --> 00:12:23,785
this rectangle node module and I'm

173
00:12:23,785 --> 00:12:29,050
passing in the length and the breadth of the first two parameters.

174
00:12:29,050 --> 00:12:31,285
And the third parameter is, of course,

175
00:12:31,285 --> 00:12:34,355
a callback function which I'm implementing here.

176
00:12:34,355 --> 00:12:38,250
So, this is an arrow function that I'm implementing here.

177
00:12:38,250 --> 00:12:40,510
So inside this callback function,

178
00:12:40,510 --> 00:12:43,245
how do I handle the return value?

179
00:12:43,245 --> 00:12:46,860
So here I'll say if (err),

180
00:12:46,860 --> 00:12:51,335
so if the error value is returned to you,

181
00:12:51,335 --> 00:12:59,500
then I will simply do console.log and I'll say

182
00:12:59,500 --> 00:13:09,100
"ERROR" and then the second value is err.message.

183
00:13:09,100 --> 00:13:11,445
Recall that in the rectangle,

184
00:13:11,445 --> 00:13:14,820
we had created this new error object

185
00:13:14,820 --> 00:13:18,155
and then passed in this string inside this error object.

186
00:13:18,155 --> 00:13:20,100
This string will be attached to

187
00:13:20,100 --> 00:13:24,380
the error object to the message property of the error object here.

188
00:13:24,380 --> 00:13:26,830
So, in the index.js file,

189
00:13:26,830 --> 00:13:30,090
so I'm retrieving the message property of the error object

190
00:13:30,090 --> 00:13:33,755
and then printing it out onto my console here.

191
00:13:33,755 --> 00:13:35,310
So if an error occurs,

192
00:13:35,310 --> 00:13:39,215
I'm going to print out the error message using this.

193
00:13:39,215 --> 00:13:45,820
And so, this is how I would handle error that was returned by a callback function.

194
00:13:45,820 --> 00:13:51,360
Otherwise, of course in this case,

195
00:13:51,360 --> 00:13:57,450
the rectangle module has returned the rectangle function,

196
00:13:57,450 --> 00:14:01,620
the object that contains the perimeter and the area functions,

197
00:14:01,620 --> 00:14:08,108
so I can go ahead and print out that value.

198
00:14:08,108 --> 00:14:14,175
So here, I'll say the area of the rectangle

199
00:14:14,175 --> 00:14:23,030
of dimensions l equal to,

200
00:14:23,140 --> 00:14:28,270
so I will say,

201
00:14:29,170 --> 00:14:37,155
and b equal to.

202
00:14:37,155 --> 00:14:40,530
The reason why I am identifying it

203
00:14:40,530 --> 00:14:47,340
explicitly will become very clear when we run this example.

204
00:14:47,340 --> 00:15:01,480
I'll say is rectangle.area.

205
00:15:01,480 --> 00:15:04,188
Now, notice that for this area,

206
00:15:04,188 --> 00:15:09,555
I am not sending in any parameters here because goes to values,

207
00:15:09,555 --> 00:15:14,540
the length and the breath have been passed in already here in the l and b,

208
00:15:14,540 --> 00:15:19,065
and those would be already available to this

209
00:15:19,065 --> 00:15:24,245
and here because of the closure that JavaScript supports.

210
00:15:24,245 --> 00:15:27,470
Because these x and y have come in as the parameters,

211
00:15:27,470 --> 00:15:32,710
so those will be accessible right there in this callback function.

212
00:15:32,710 --> 00:15:37,315
So those x_y will be automatically available for us here.

213
00:15:37,315 --> 00:15:39,890
So, as a matter of fact,

214
00:15:39,890 --> 00:15:43,970
I don't need to supply this x and y parameters here at all because

215
00:15:43,970 --> 00:15:49,090
those x and y will be retrieved from this x and y right there.

216
00:15:49,090 --> 00:15:53,375
So I don't even need to pass those two values in here.

217
00:15:53,375 --> 00:15:55,385
So that's why, right there,

218
00:15:55,385 --> 00:15:57,905
I can call rectangle.area.

219
00:15:57,905 --> 00:16:03,170
And this area computation will automatically get the l and b that have been passed in

220
00:16:03,170 --> 00:16:09,505
by the rectangle call to direct node module earlier.

221
00:16:09,505 --> 00:16:14,980
So this is the closure of JavaScript operating here.

222
00:16:14,980 --> 00:16:17,945
So, that is the first one.

223
00:16:17,945 --> 00:16:23,305
I am printing out the area of the rectangle.

224
00:16:23,305 --> 00:16:32,990
The same thing, let me also print out the perimeters.

225
00:16:32,990 --> 00:16:34,608
So to print out the perimeters,

226
00:16:34,608 --> 00:16:36,720
so I'll say console.log.

227
00:16:36,720 --> 00:16:46,560
The perimeter of the rectangle will be rectangle perimeter.

228
00:16:46,560 --> 00:16:53,280
Now, I must tell you that this kind of approach for implementing takes a little bit

229
00:16:53,280 --> 00:17:02,335
of effort to understand and internalize the asynchronous function ability.

230
00:17:02,335 --> 00:17:06,360
Takes some time for you to completely understand how it really works.

231
00:17:06,360 --> 00:17:08,550
Now to illustrate the fact that

232
00:17:08,550 --> 00:17:14,642
this function call will result in a call to the Node module

233
00:17:14,642 --> 00:17:19,280
but this part will be executed only after

234
00:17:19,280 --> 00:17:24,830
a two-second delay because of the fact that we are using the set time mark.

235
00:17:24,830 --> 00:17:28,745
Now, as we studied in asynchronous operation,

236
00:17:28,745 --> 00:17:33,155
because we have moved off the processing to the back,

237
00:17:33,155 --> 00:17:41,420
let me also introduce one more console.log here to make a point.

238
00:17:41,420 --> 00:17:46,175
So we'll say this statement is

239
00:17:46,175 --> 00:17:53,869
after the call to rect.

240
00:17:53,869 --> 00:18:00,210
The reason why I am illustrating this point is that when you issue this call,

241
00:18:00,210 --> 00:18:06,130
this code will not be executed until after a two-second delay.

242
00:18:06,130 --> 00:18:08,070
So, in the meantime,

243
00:18:08,070 --> 00:18:10,360
your function, main function here,

244
00:18:10,360 --> 00:18:16,340
will continue on and then execute the next line of code that you see here.

245
00:18:16,340 --> 00:18:19,745
So this is the continuation that you will see here.

246
00:18:19,745 --> 00:18:21,805
So, with these changes,

247
00:18:21,805 --> 00:18:27,815
let's save the changes and then look at how this application executes now.

248
00:18:27,815 --> 00:18:29,410
So saving the changes.

249
00:18:29,410 --> 00:18:35,220
Let's go to the terminal and execute this node application.

250
00:18:35,220 --> 00:18:37,570
Now, going to the terminal, add the prompt.

251
00:18:37,570 --> 00:18:43,795
Let me type npm start and you will immediately notice

252
00:18:43,795 --> 00:18:51,790
that the solve and this statement were printed out earlier.

253
00:18:51,790 --> 00:18:54,505
And then after this certain delay,

254
00:18:54,505 --> 00:18:57,855
the area and the perimeter was printed out.

255
00:18:57,855 --> 00:19:02,130
So that is a two-second delay that we introduced using the set time out.

256
00:19:02,130 --> 00:19:05,755
So, you noticed that in the earlier version,

257
00:19:05,755 --> 00:19:10,290
this was printed and immediately the area and the perimeter was printed right below that.

258
00:19:10,290 --> 00:19:15,120
But now, notice that those values are printed a little bit later.

259
00:19:15,120 --> 00:19:20,460
So in between, their function calls with the different parameters that are already gone

260
00:19:20,460 --> 00:19:26,505
in and then the callbacks are called back after two second delay for each one of them.

261
00:19:26,505 --> 00:19:32,500
And because of the fact that there is the closure that the JavaScript supports,

262
00:19:32,500 --> 00:19:35,980
so the values that get passed in is preserved.

263
00:19:35,980 --> 00:19:38,440
And so when the callback function is called,

264
00:19:38,440 --> 00:19:40,615
the appropriate value is printed.

265
00:19:40,615 --> 00:19:42,730
So that's why you see that the area and

266
00:19:42,730 --> 00:19:46,330
the perimeter are printed correctly and these two here,

267
00:19:46,330 --> 00:19:48,070
these two statements here,

268
00:19:48,070 --> 00:19:51,340
correspond to this particular call to direct

269
00:19:51,340 --> 00:19:55,100
with l is equal to two and b is equal to four.

270
00:19:55,100 --> 00:19:56,605
And then these two,

271
00:19:56,605 --> 00:19:58,150
the next to two, of course,

272
00:19:58,150 --> 00:20:05,000
correspond to this particular one and the remaining ones as you see here.

273
00:20:05,000 --> 00:20:10,410
So, what I wanted to illustrate is the fact that when you do asynchronous computation,

274
00:20:10,410 --> 00:20:12,730
the asynchronous computation takes its own time

275
00:20:12,730 --> 00:20:16,270
to return the value while your main computation

276
00:20:16,270 --> 00:20:22,460
will proceed forward without waiting for the callback to be completed.

277
00:20:22,460 --> 00:20:25,245
So, when you need to do a certain amount of work,

278
00:20:25,245 --> 00:20:29,365
you passed in as a callback to that other module.

279
00:20:29,365 --> 00:20:31,375
And when that other module completes its work,

280
00:20:31,375 --> 00:20:35,010
it's going to callback and then that code will be executed.

281
00:20:35,010 --> 00:20:40,350
So that is the point that I have illustrated using this example.

282
00:20:40,350 --> 00:20:41,565
Again, as I said,

283
00:20:41,565 --> 00:20:45,210
this takes a little bit of imagination and understanding

284
00:20:45,210 --> 00:20:48,930
for you to internalize the way this works,

285
00:20:48,930 --> 00:20:55,185
but you will see that with Node and also Express and when we use MongoDB,

286
00:20:55,185 --> 00:21:01,785
you will see this kind of pattern repeating very often in the way we write our code.

287
00:21:01,785 --> 00:21:06,210
So with this simple illustration of callbacks and error handling,

288
00:21:06,210 --> 00:21:08,940
we complete this exercise.

289
00:21:08,940 --> 00:21:13,675
This is a good time for you to do a get comment with that message,

290
00:21:13,675 --> 00:21:17,700
node, callbacks, and error handling.