WEBVTT

0
00:00.120 --> 00:07.170
So far in our code we've been using and requiring all of these Node modules for example EJS or Express

1
00:07.260 --> 00:08.660
and body-parser.

2
00:08.970 --> 00:11.580
But how does it actually work?

3
00:11.580 --> 00:18.870
If we take a look inside our Node modules and we go and just find where EJS is, and we click on

4
00:19.010 --> 00:19.370
ejs.

5
00:19.380 --> 00:25.200
js, if you scroll down it, you can see that there is-- maybe there are some variables which we already

6
00:25.200 --> 00:31.470
know about, there's some functions but there's also a whole bunch of these exports: exports.this export.

7
00:31.680 --> 00:32.430
that.

8
00:32.430 --> 00:34.800
So what exactly is that?

9
00:35.190 --> 00:42.480
Let's try and understand how our Node modules like EJS, Express, body-parser actually work by creating

10
00:42.600 --> 00:45.790
a module of our own from scratch.

11
00:46.830 --> 00:54.930
Currently we have this thing down here which basically just generates the current day in a particular

12
00:54.930 --> 00:56.880
format that we desired.

13
00:57.210 --> 01:03.390
Now if we were to refactor our code right now then this is probably one of the first things that we

14
01:03.390 --> 01:12.150
want to package into its own module because it doesn't really belong here in the app.js. You can imagine

15
01:12.150 --> 01:16.970
that as our app.js gets more and more complex, then we have more routes,

16
01:16.980 --> 01:21.560
we have different get, post routes all over the place.

17
01:21.600 --> 01:29.590
Code that's not strictly related to the route shouldn't actually be in here cluttering the app.

18
01:29.610 --> 01:31.130
js.

19
01:31.340 --> 01:32.870
How would you normally solve this?

20
01:32.870 --> 01:35.570
Well we could go ahead and create a new file

21
01:35.600 --> 01:41.750
let's just call it date.js and this could be our own little module for generating the current

22
01:41.870 --> 01:42.740
date.

23
01:42.770 --> 01:46.140
So let's go ahead and cut all of this code.

24
01:47.230 --> 01:55.480
And we're going to paste it inside date.js. And of course we have to again say jshint we're

25
01:55.480 --> 01:59.650
using esversion 6.

26
01:59.770 --> 02:07.210
Now we have this date.js module which does all of the hard work to find the date and change it

27
02:07.210 --> 02:08.680
to a particular format.

28
02:08.680 --> 02:12.850
But how do we get this day back into our app.

29
02:12.930 --> 02:16.770
js and use it inside our root route?

30
02:17.230 --> 02:24.780
Well maybe we could wrap this thing inside a function, we could call it getDate. And this function

31
02:24.790 --> 02:32.770
all it does is carries out all of this code and then it simply returns the result of all of this.

32
02:32.770 --> 02:38.890
So at the end we get this thing called Day which is what we've been previously using inside our root

33
02:38.890 --> 02:39.600
route.

34
02:39.610 --> 02:43.240
So what if we just returned day

35
02:43.470 --> 02:46.470
so we get an output out of our function?

36
02:46.470 --> 02:52.840
Now we have this function and we have a way for it to return the thing that we want.

37
02:53.100 --> 02:55.380
How do we actually export it?

38
02:55.380 --> 02:58.250
How do we get it out of this date.js?

39
02:58.800 --> 03:02.990
How can we make it available elsewhere if it's needed?

40
03:03.480 --> 03:07.360
Well this is where Node comes in to the rescue.

41
03:07.440 --> 03:14.640
So if you take a look at the docs for the latest version then if you read through all of this maybe

42
03:14.640 --> 03:23.490
not all of it but the relevant parts, then you can see that there's a section on modules. And the module

43
03:23.550 --> 03:31.300
object is basically something that gives you a reference to the object that represents the current module.

44
03:31.530 --> 03:35.500
So that means that inside this module here date.

45
03:35.500 --> 03:39.210
.js, we have access to this thing called module.

46
03:39.420 --> 03:50.550
And I can go ahead and just log my module. And if I were to use this module then I can require this module

47
03:50.880 --> 03:53.500
to run all the code inside here.

48
03:53.730 --> 04:00.810
So for example, up here instead of requiring body-parser and Express I'm going to create a new const called

49
04:00.870 --> 04:05.310
date and this simply requires my new date module.

50
04:05.700 --> 04:12.450
Now because our module is local and has not installed using NPM then the way we access it is a little

51
04:12.450 --> 04:13.300
bit different.

52
04:13.470 --> 04:18.720
We have to use that thing that we saw previously with the directory name +

53
04:18.780 --> 04:22.150
and then we have to locate our date.js.

54
04:22.410 --> 04:29.460
So now what this will do is we're saying we're requiring a module and it's located at the current directory

55
04:29.820 --> 04:36.810
name and then we add /.js in order to access this particular file.

56
04:37.470 --> 04:45.330
So now if I hit save and I run my code using node app.js making sure that you're in the right

57
04:45.330 --> 04:52.050
position then I will end up with my module printed out inside my console.

58
04:52.290 --> 05:01.390
So whenever I say require this module then it'll go into this module and it'll try to run all of this code.

59
05:01.470 --> 05:08.850
Now over here you can see what it's running is that log statement. And we've logged that module object

60
05:08.850 --> 05:15.210
so this is the object that represents our date module. And you can see it's got a whole bunch of interesting

61
05:15.210 --> 05:15.970
things in here.

62
05:15.990 --> 05:17.430
For example an id

63
05:17.460 --> 05:25.230
so this is where it's located which currently is in my local directory right? Something called WebDev

64
05:25.230 --> 05:30.780
/todolist-v1/date.js which is where you can see it here.

65
05:31.080 --> 05:33.660
And then you've got a whole bunch of other things such as

66
05:33.750 --> 05:35.550
it's got a parent module right?

67
05:35.550 --> 05:38.910
What was the model that actually launched it or required it?

68
05:38.910 --> 05:46.350
Well in this case it's something called app.js. And that thing has a whole bunch of children including

69
05:46.380 --> 05:47.750
this date module.

70
05:47.790 --> 05:55.290
So we've also got other children such as Express and body-parser and EJS and it's also got other things

71
05:55.350 --> 05:56.810
associated to it.

72
05:57.070 --> 06:03.630
Now if we take a look at our module object that represents our date module you can see it's also got

73
06:03.630 --> 06:10.920
this property called exports. And export seems to be some sort of Javascript object as denoted by those

74
06:10.920 --> 06:11.980
curly braces.

75
06:12.180 --> 06:14.840
But at the moment it's completely empty.

76
06:14.910 --> 06:19.830
So there is nothing that our module is exporting.

77
06:19.940 --> 06:25.800
If we take a look back at the documentation and we navigate to this part where it talks about module

78
06:25.810 --> 06:33.930
.exports, then you can see that this is also a Javascript object and it's created by the module system.

79
06:33.950 --> 06:41.780
So what it allows us to do is to basically say module.exports do something or is equal to something.

80
06:42.200 --> 06:49.040
And then that means that in another file, we can simply tap into that module and use some of those exports.

81
06:49.040 --> 06:51.960
So let me show it to you in our code.

82
06:52.370 --> 07:00.760
Now instead of console logging our module, we can simply write module.exports.

83
07:00.800 --> 07:01.720
Remember the s

84
07:01.730 --> 07:04.100
this is a really common mistake.

85
07:04.100 --> 07:08.060
And then we set it to equal say hello world

86
07:08.060 --> 07:14.610
maybe. Now this current date module exports the string that's Hello world.

87
07:14.630 --> 07:16.730
So if we go back into our app.

88
07:16.730 --> 07:23.380
js whenever we require our module it gets bound to something called date.

89
07:23.630 --> 07:32.600
And over here we can simply log our date object and that will be equal to whatever it is that we exported

90
07:32.900 --> 07:35.050
out of this module.

91
07:35.060 --> 07:43.220
So now if I had back into my console and I stopped my server and rerun it, you can see that my app.

92
07:43.250 --> 07:45.010
js is now printing

93
07:45.020 --> 07:46.180
Hello world.

94
07:46.220 --> 07:48.560
There's no log statements over here.

95
07:48.830 --> 07:52.000
And this is because I'm exporting from this module

96
07:52.010 --> 07:56.710
just a simple string and it's now available inside my app.

97
07:56.720 --> 08:03.810
js. Now they were able to get access to the exports from this module,

98
08:03.970 --> 08:08.650
what if we wanted to get access to a function instead?

99
08:08.740 --> 08:13.810
For example what if we wanted to be able to tap into this function?

100
08:14.080 --> 08:22.180
Well if instead of setting our module.exports to equal hello world, we can set it to equal getDate.

101
08:22.180 --> 08:28.720
Now the important thing with Javascript object is when you decide to add the parentheses because the

102
08:28.720 --> 08:34.320
time when you add the parentheses then that means we're actually calling, we're activating the function

103
08:34.360 --> 08:34.950
right?

104
08:35.200 --> 08:41.770
And we don't want to do that inside our module because we want to allow the app.js to determine

105
08:41.890 --> 08:45.900
when that function should be called.

106
08:45.910 --> 08:54.100
So currently our date object here is bound to the exports of our date module and the exports of our date module

107
08:54.310 --> 08:56.800
is simply just a function.

108
08:56.800 --> 09:04.990
So if I were to log date as it is right now, you can see that it's only going to tell me that it's just

109
09:04.990 --> 09:07.270
a function and it's called getDate.

110
09:07.360 --> 09:13.870
It's not going to actually run that function and give me the return statement which is the actual date

111
09:13.900 --> 09:15.120
that I'm looking for.

112
09:15.340 --> 09:19.890
If I want it to run then I have to add my parentheses.

113
09:20.080 --> 09:27.820
So now when I rerun my app.js you can see now it's running the function get date rather than just

114
09:27.880 --> 09:30.390
logging the actual function.

115
09:30.520 --> 09:38.070
Now by binding our exports to this function inside the module, we're now able to export it into our app.js 

116
09:38.080 --> 09:41.660
and we can use it anywhere we like.

117
09:41.710 --> 09:45.560
So we don't have to activate it when we require it,

118
09:45.910 --> 09:48.520
we can add it wherever it's needed.

119
09:48.520 --> 09:58.390
So for example inside our app.get, we're now able to say date run or whatever is bound to that module

120
09:58.600 --> 10:02.930
and let's say we save it inside something called day

121
10:02.980 --> 10:03.600
right?

122
10:03.970 --> 10:10.270
So now we have this thing called day which is bound to the output of this date module which currently

123
10:10.360 --> 10:17.840
is getting us the current date because it's running this function getDate. What we're saying here

124
10:17.870 --> 10:26.540
is we have this module called date and we're requiring it up here which binds all of the exports to this

125
10:26.540 --> 10:35.780
constant called date. And then down here we call the function that's bound to that constant date and we

126
10:35.780 --> 10:42.560
activate our getDate function. And now we have the result of it stored inside day which we're going

127
10:42.560 --> 10:44.420
to pass over here.

128
10:44.420 --> 10:48.570
Now we're able to head over to our console and run our app.j

129
10:48.600 --> 10:49.130
js.

130
10:49.430 --> 10:58.250
And now if we head over to our localhost:3000, you can see it's passing the output of that date module

131
10:58.610 --> 11:01.470
into our title over here.

132
11:02.120 --> 11:10.370
So we've managed to move our date code out of our app.js put it into its own separate module and

133
11:10.370 --> 11:15.500
we're able to use it inside app.js or any other file for that matter.

134
11:15.500 --> 11:20.150
And now this code in our date.js is completely reusable.

135
11:20.330 --> 11:25.000
We can require it and use it anywhere we like.

136
11:25.370 --> 11:32.570
But what if we wanted our date module to do more than one thing because at the moment all it exports

137
11:32.660 --> 11:35.380
is just one function right?

138
11:35.420 --> 11:38.210
It kind of makes its functionality quite limited.

139
11:38.450 --> 11:44.670
What if we had say another function right? Down here. Let's say we had a function, instead of  getdate

140
11:44.690 --> 11:46.670
it's gets the day right?

141
11:46.670 --> 11:50.360
The current day of the week. And pretty much all of this is the same

142
11:50.360 --> 11:58.310
other than this option we only want the weekday to be in a long format and then we bind it to this thing

143
11:58.310 --> 12:03.620
called day and we return it as the output of this function.

144
12:03.800 --> 12:12.530
Now because our module.exports is only bound to getDate to function, we can't seem to access this

145
12:12.530 --> 12:14.100
getDay.

146
12:14.300 --> 12:15.520
How do we solve this?

147
12:15.680 --> 12:23.600
Well if you remember previously I mentioned that module.export is a Javascript object.

148
12:24.230 --> 12:29.600
And objects have properties and methods associated with it.

149
12:29.900 --> 12:39.020
So that means that instead of simply binding the entire object to our getDate function, I could say module

150
12:39.030 --> 12:51.040
.exports.geDate is equal to this function. And that means that I can do the same thing down

151
12:51.040 --> 13:01.450
here and say model.exports.getDay is equal to the getDay function.

152
13:01.480 --> 13:10.820
So now if at the end of all of this code we log our module.exports and we go back into our app.

153
13:10.850 --> 13:15.700
.js and require that module,

154
13:16.150 --> 13:24.360
then you can see that currently our exports object now has two functions that are tied to it.

155
13:24.400 --> 13:33.160
One is called getDay and one is called getDate. Now inside our app.js, instead of saying just run

156
13:33.220 --> 13:37.440
the function that's bound to the exports from our data module

157
13:37.540 --> 13:43.000
we can say run the function that's bound to our date module .getDate.

158
13:46.050 --> 13:49.010
And this will work exactly the same way as before

159
13:49.020 --> 13:55.440
so I can restart my server and you can see that it's still working as expected

160
13:55.620 --> 14:02.430
but now I have the option of saying, 'Oh maybe instead I just want the actual day of the week.'

161
14:02.430 --> 14:11.160
So now if I go ahead and restart my server and refresh my website, you can see I'm using the getDay

162
14:11.340 --> 14:17.080
function inside our date module to just bring up the actual day of the week.

163
14:18.470 --> 14:25.490
This is how we can create our own modules and require them and get their functionality exported out of

164
14:25.490 --> 14:28.910
the module to be used anywhere within our project.

165
14:28.910 --> 14:32.000
So this makes it reusable and way more useful.

166
14:32.000 --> 14:35.830
So this is the first step in our refactoring.

167
14:35.900 --> 14:39.890
Now the next step is how can we make this a little bit more succinct?

168
14:39.890 --> 14:41.360
How can we make it a bit shorter

169
14:41.390 --> 14:43.670
because at the moment it's quite wordy

170
14:43.670 --> 14:44.340
right?

171
14:44.750 --> 14:51.680
So for example here where we're creating let day equals this and then return day, then we can simply

172
14:51.680 --> 14:57.050
get rid of all of this and just say return this

173
14:57.090 --> 14:57.450
right?

174
14:57.510 --> 15:02.970
So we can now delete that and we can do the same over here.

175
15:02.970 --> 15:08.990
We can simply just return that without having to bind it to another variable.

176
15:09.030 --> 15:16.530
The next thing we can look at is for example here we're saying module.export.getDate equals

177
15:16.530 --> 15:20.410
getDate function getDate this getDate-- like all over the place

178
15:20.430 --> 15:21.190
right?

179
15:21.210 --> 15:23.420
So how can we simplify this?

180
15:23.730 --> 15:29.460
Well you might remember from earlier lessons that we mentioned that Javascript functions can be declared

181
15:29.550 --> 15:36.990
in a variety of ways. And in the course resources a link to this particular blog post which does a really

182
15:36.990 --> 15:42.920
good job of summarizing the 6 different ways that you can declare Javascript functions.

183
15:42.930 --> 15:45.440
So there's a lot of different ways that you can do it.

184
15:45.630 --> 15:51.240
Now the way that we're most used to is just a simple function declaration.

185
15:51.330 --> 15:56.100
It's the function keyword, the name of the function, some inputs and maybe some outputs

186
15:56.100 --> 16:05.190
right? Now another way of doing this is by using a function expression. We could set our function to equal

187
16:05.280 --> 16:07.260
a variable instead.

188
16:07.320 --> 16:12.620
And this means that we can pass our function around whenever we need it.

189
16:12.630 --> 16:18.400
So now we have an anonymous function that's set to equal a variable with a name

190
16:18.600 --> 16:24.960
and whenever we need that functionality we simply just refer to it by its name.

191
16:25.020 --> 16:31.020
So let's implement it to understand it a bit better. Instead of having our getDate as a normal Javascript

192
16:31.020 --> 16:31.640
function,

193
16:31.650 --> 16:37.650
I'm going to change it into an anonymous function so this function doesn't have a name anymore. And instead

194
16:37.680 --> 16:41.290
we're going to bind it to a variable that's called getDate.

195
16:41.630 --> 16:47.760
And now this getDate variable is bound to our anonymous function.

196
16:48.300 --> 16:51.190
And you can see now this is a little bit clearer.

197
16:51.270 --> 16:57.480
Instead of saying module.exports.getDate = getDate which is basically the contents of

198
16:57.480 --> 16:59.640
everything after the equal sign,

199
16:59.700 --> 17:08.400
then we can simply delete all this and say module.exports.getDate is now equal to this anonymous

200
17:08.400 --> 17:09.770
function.

201
17:10.410 --> 17:17.100
And this means that we save on two get dates and we make everything a little bit more succinct.

202
17:17.340 --> 17:20.210
Let's go ahead and do the same thing over here.

203
17:20.340 --> 17:25.220
Let's delete this name of the function to turn it into an anonymous function

204
17:25.410 --> 17:32.960
and we're simply going to set that function to equal module.exports.getDay.

205
17:33.030 --> 17:41.640
Now we can make this even shorter by reading through our node.js documentation because if you scroll

206
17:41.640 --> 17:48.540
down a little bit, you can see that node.js actually provides an export shortcut because just how often

207
17:48.600 --> 17:49.950
it's used.

208
17:49.950 --> 17:58.890
So instead of using module.exports we can simply just use the exports variable to refer to exactly

209
17:58.890 --> 18:00.240
the same thing.

210
18:00.840 --> 18:07.470
So here instead of saying module.exports, we can just say exports for short and it will refer to

211
18:07.470 --> 18:10.610
the same thing which is module.exports.

212
18:10.650 --> 18:11.920
So now let's hit save.

213
18:11.970 --> 18:14.020
I'm going to delete this console log

214
18:14.070 --> 18:23.670
and over here in my app.js I'm using date.getDate from my date module and I'm rendering it

215
18:23.850 --> 18:26.470
as my list title.

216
18:26.490 --> 18:33.810
So if we go ahead and launch our app now with nodemon to save ourselves the effort of restarting our

217
18:33.810 --> 18:40.680
server all the time, then we can refresh and you can see our app works exactly the same.

218
18:40.680 --> 18:45.710
Now while refactoring, we might as well try and refactor the rest of our code.

219
18:45.720 --> 18:48.160
For example we've got a lot of let around here.

220
18:48.180 --> 18:52.540
So these are variables but actually these variables are never going to vary.

221
18:52.590 --> 18:57.960
So we can simply change it to const, const here as well

222
18:58.110 --> 19:07.470
and const down here. Now because we're never really re-assigning the values of today or options, then

223
19:07.560 --> 19:10.170
this won't change our code at all.

224
19:10.170 --> 19:13.470
It still works exactly the same way.

225
19:13.500 --> 19:17.700
Now back in our app.js we can do some more of that refactoring.

226
19:17.700 --> 19:25.230
For example here where we're changing the items array into a const and you might say hey wait a minute,

227
19:25.690 --> 19:31.520
what-- we're going to change this right? We're going to add new items to this array.

228
19:31.590 --> 19:33.800
So how do we make it a constant?

229
19:34.200 --> 19:40.200
Well this is a little bit of a quirk of Javascript and it's not this way in some languages

230
19:40.230 --> 19:47.130
and it varies from language to language. But for Javascript at least, if you take a look at the MDN docs

231
19:47.220 --> 19:54.480
for const and you scroll down at some of their examples, you can see that when they talk about arrays

232
19:54.630 --> 20:04.460
when we create a constant which is an array, it's actually possible to push new items into the array.

233
20:04.630 --> 20:09.660
But it's not possible to simply assign it to a brand new array.

234
20:09.670 --> 20:14.470
This is one of the things that doesn't really stay constant.

235
20:14.470 --> 20:20.470
The other thing that doesn't stay constant is when you have an object and you can't change that object

236
20:20.560 --> 20:22.770
into an entirely new object

237
20:22.780 --> 20:23.020
right?

238
20:23.020 --> 20:28.020
This will throw an error because my object was declared as constant.

239
20:28.210 --> 20:35.800
But if you try to change one of the values that's associated with one of the keys inside the object,

240
20:36.100 --> 20:37.750
then you actually can

241
20:37.750 --> 20:40.480
even though this thing is a constant.

242
20:40.810 --> 20:46.810
So it's important to remember that when you declare something as constant in Javascript it's not protecting

243
20:46.810 --> 20:49.240
the things that's inside that thing,

244
20:49.240 --> 20:56.230
so inside the array or inside the object. You're still able to vary those things. You just can't assign

245
20:56.230 --> 21:00.220
it to a new entirely different object or array.

246
21:00.580 --> 21:08.920
So that means over here if we change all of those lets to consts, then it will still work just as well

247
21:09.340 --> 21:12.460
and we won't actually come into any problems.

248
21:12.610 --> 21:18.680
So let's hit save and nodemon's updating our server behind the scenes. And refresh our website

249
21:18.790 --> 21:24.850
you can see that we're still getting the data here and we're still able to add items into our array

250
21:25.660 --> 21:28.750
and cross them out as needed.

251
21:28.780 --> 21:35.560
So I hope you enjoyed learning about EJS and templating with me in this module. In the next module we're

252
21:35.560 --> 21:42.040
going to see if you can apply everything that we learned about EJS and templating into your very own

253
21:42.040 --> 21:42.650
project.

254
21:42.700 --> 21:45.220
So head over to the challenge once you're ready.