1
00:00:02,130 --> 00:00:04,150
Now that we know how to parse

2
00:00:04,150 --> 00:00:05,980
and use submitted data,

3
00:00:05,980 --> 00:00:08,780
we finally can do something,

4
00:00:08,780 --> 00:00:11,150
which we were not able to do before.

5
00:00:11,150 --> 00:00:13,490
We can now actually handle the submission

6
00:00:13,490 --> 00:00:17,260
of a form here on our own server.

7
00:00:17,260 --> 00:00:20,190
So with our own server-side code.

8
00:00:20,190 --> 00:00:21,023
And that, of course,

9
00:00:21,023 --> 00:00:24,260
means that we could now also handle more complex forms

10
00:00:24,260 --> 00:00:27,820
as we built them before in the forms section of this course

11
00:00:27,820 --> 00:00:29,870
but it is something we'll come back to later

12
00:00:29,870 --> 00:00:32,333
once we build more realistic projects.

13
00:00:33,690 --> 00:00:36,000
For the moment, let's instead dive in deeper,

14
00:00:36,000 --> 00:00:38,570
and let's do more interesting things

15
00:00:38,570 --> 00:00:42,110
that we can do now with NodeJS and Express

16
00:00:42,110 --> 00:00:43,710
that we couldn't do before

17
00:00:43,710 --> 00:00:47,653
with just HTML, CSS and browser-side JavaScript.

18
00:00:48,500 --> 00:00:50,370
And the next thing I wanna do

19
00:00:50,370 --> 00:00:53,180
is I wanna store the usernames,

20
00:00:53,180 --> 00:00:57,150
which are submitted by users in an actual text file.

21
00:00:57,150 --> 00:00:59,610
We could also store it in a database

22
00:00:59,610 --> 00:01:02,030
but that requires a bit more knowledge.

23
00:01:02,030 --> 00:01:04,560
We'll gain that throughout the course as well.

24
00:01:04,560 --> 00:01:07,640
But starting with a text file is good enough for now,

25
00:01:07,640 --> 00:01:10,920
and shows us how we can access the file system

26
00:01:10,920 --> 00:01:14,543
of our server with Node and Express code.

27
00:01:15,670 --> 00:01:20,090
And for this, my goal is to add a new data folder here.

28
00:01:20,090 --> 00:01:22,350
Name is up to you but I'll call it data,

29
00:01:22,350 --> 00:01:25,460
and in that folder, I'll add a new file,

30
00:01:25,460 --> 00:01:28,523
the users.json file.

31
00:01:29,710 --> 00:01:32,238
Now, I'm using this .json extension

32
00:01:32,238 --> 00:01:34,900
to make it clear that the content

33
00:01:34,900 --> 00:01:38,190
in this file should follow this JSON format,

34
00:01:38,190 --> 00:01:40,560
which I already did show you here

35
00:01:40,560 --> 00:01:44,260
when we had a look at the package.json file.

36
00:01:44,260 --> 00:01:47,450
I'm using this format instead of a regular text file

37
00:01:47,450 --> 00:01:49,660
since reading and writing JSON data

38
00:01:49,660 --> 00:01:53,180
is very easy for machines, for computers,

39
00:01:53,180 --> 00:01:56,390
and therefore, we can easily store complex data,

40
00:01:56,390 --> 00:01:59,350
like a list of usernames in such a file

41
00:01:59,350 --> 00:02:00,950
without having to write a bunch

42
00:02:00,950 --> 00:02:04,400
of extra logic for then parsing that data correctly

43
00:02:04,400 --> 00:02:05,393
and so on.

44
00:02:06,720 --> 00:02:10,419
At the moment though, this users.json file is empty,

45
00:02:10,419 --> 00:02:12,070
at least almost empty.

46
00:02:12,070 --> 00:02:13,890
The only thing I'll add here

47
00:02:13,890 --> 00:02:17,300
is opening and closing square brackets.

48
00:02:17,300 --> 00:02:20,380
So like an array but an empty array.

49
00:02:20,380 --> 00:02:21,960
And also just that.

50
00:02:21,960 --> 00:02:24,580
No variable name or anything like that

51
00:02:24,580 --> 00:02:26,760
because this is not JavaScript code,

52
00:02:26,760 --> 00:02:29,830
this is just a text file following a certain text format,

53
00:02:29,830 --> 00:02:33,820
and hence, I really just have that empty array in here.

54
00:02:33,820 --> 00:02:37,083
And then I'll save users.json and close that file.

55
00:02:37,980 --> 00:02:40,170
Now I wanna open that file here

56
00:02:40,170 --> 00:02:43,530
in the post method and add a username to that array

57
00:02:43,530 --> 00:02:45,713
so that the array doesn't stay empty.

58
00:02:46,610 --> 00:02:48,070
And to achieve this,

59
00:02:48,070 --> 00:02:50,330
we'll use another package.

60
00:02:50,330 --> 00:02:54,060
Again, a package that's built into NodeJS,

61
00:02:54,060 --> 00:02:57,313
so not a package that we have to install separately.

62
00:02:58,240 --> 00:02:59,930
For this, I'll require it,

63
00:02:59,930 --> 00:03:03,470
and the package I wanna require is the fs package,

64
00:03:03,470 --> 00:03:05,673
which stands for file system.

65
00:03:06,860 --> 00:03:10,280
Now, I'll require it first before I require Express,

66
00:03:10,280 --> 00:03:12,940
though the order actually doesn't matter

67
00:03:12,940 --> 00:03:14,830
but it is the convention

68
00:03:14,830 --> 00:03:18,560
to always require core NodeJS packages

69
00:03:18,560 --> 00:03:21,630
that are built into NodeJS first

70
00:03:21,630 --> 00:03:24,950
before you require any possible third-party packages

71
00:03:24,950 --> 00:03:26,053
you might be using.

72
00:03:27,260 --> 00:03:30,900
And then again, I store the content of that package,

73
00:03:30,900 --> 00:03:33,300
which in this case, will again be an object

74
00:03:33,300 --> 00:03:36,200
in a variable or constant.

75
00:03:36,200 --> 00:03:37,630
The constant name is up to you

76
00:03:37,630 --> 00:03:40,130
but since this is the file system package,

77
00:03:40,130 --> 00:03:42,493
I'll give that constant the same name.

78
00:03:43,770 --> 00:03:46,540
And now we can use the object stored in this constant

79
00:03:46,540 --> 00:03:49,620
to perform file system operations.

80
00:03:49,620 --> 00:03:51,960
Instead of console.logging the username,

81
00:03:51,960 --> 00:03:54,570
I now wanna use that fs package

82
00:03:54,570 --> 00:03:58,570
to then open this file, this users.json file,

83
00:03:58,570 --> 00:04:00,040
which we have in the data folder,

84
00:04:00,040 --> 00:04:02,490
and write data into it.

85
00:04:02,490 --> 00:04:06,470
For that, we have the writeFileSync method here,

86
00:04:06,470 --> 00:04:09,740
and it's important that you use the sync method

87
00:04:09,740 --> 00:04:12,950
since that will perform the operation instantly,

88
00:04:12,950 --> 00:04:15,110
which is what we want here.

89
00:04:15,110 --> 00:04:17,190
And to writeFileSync,

90
00:04:17,190 --> 00:04:19,370
you now have to pass a path

91
00:04:19,370 --> 00:04:23,173
to the file where this data should be written to.

92
00:04:24,320 --> 00:04:27,650
Now, that is the users.json file in the data folder,

93
00:04:27,650 --> 00:04:30,130
so in that data subfolder,

94
00:04:30,130 --> 00:04:33,510
and hence, the full path includes both the folder name

95
00:04:33,510 --> 00:04:34,763
and the file name.

96
00:04:36,060 --> 00:04:38,820
Now, to construct that path in a way

97
00:04:38,820 --> 00:04:41,970
that will work on all operating systems,

98
00:04:41,970 --> 00:04:44,500
I will require another core package

99
00:04:44,500 --> 00:04:45,860
that's built into Node,

100
00:04:45,860 --> 00:04:48,166
and that's the path package,

101
00:04:48,166 --> 00:04:50,963
which helps us with constructing paths.

102
00:04:51,820 --> 00:04:55,740
I'll also store this here in a constant.

103
00:04:55,740 --> 00:04:57,460
The path package makes it easy

104
00:04:57,460 --> 00:04:59,650
to construct complete paths

105
00:04:59,650 --> 00:05:02,330
that will work on all operating systems

106
00:05:02,330 --> 00:05:03,823
with minimal effort.

107
00:05:04,800 --> 00:05:08,010
And we can use this required path package here now

108
00:05:08,010 --> 00:05:10,280
to construct our filePath,

109
00:05:10,280 --> 00:05:13,040
which I'll store in a separate constant

110
00:05:13,040 --> 00:05:15,203
by using path.join.

111
00:05:16,350 --> 00:05:18,320
And then here we now want

112
00:05:18,320 --> 00:05:22,310
to join multiple fragments together

113
00:05:22,310 --> 00:05:24,480
that describe the overall path

114
00:05:24,480 --> 00:05:26,343
where the data should be stored in.

115
00:05:27,770 --> 00:05:29,300
Now, the important thing here

116
00:05:29,300 --> 00:05:34,300
is that this path actually has to be an absolute path.

117
00:05:34,600 --> 00:05:37,830
And therefore, we have to start with the path

118
00:05:37,830 --> 00:05:39,853
of our project directory.

119
00:05:40,750 --> 00:05:42,210
Now, we could look this up

120
00:05:42,210 --> 00:05:45,500
and see which path that is on our operating system

121
00:05:45,500 --> 00:05:46,860
but it's far easier

122
00:05:46,860 --> 00:05:50,630
if we use a special globally available variable

123
00:05:50,630 --> 00:05:52,880
that is exposed by NodeJS.

124
00:05:52,880 --> 00:05:57,740
And that's the __dirname variable.

125
00:05:57,740 --> 00:06:00,630
And it's important that you have two underscores

126
00:06:00,630 --> 00:06:02,200
at the beginning.

127
00:06:02,200 --> 00:06:04,020
This name might look strange

128
00:06:04,020 --> 00:06:07,170
but it is a valid JavaScript variable name,

129
00:06:07,170 --> 00:06:10,490
and it's a built-in variable or constant

130
00:06:10,490 --> 00:06:12,920
that actually holds the absolute path

131
00:06:12,920 --> 00:06:14,763
to this project directory.

132
00:06:16,010 --> 00:06:18,550
And now we can add multiple arguments

133
00:06:18,550 --> 00:06:20,560
by separating them with commas

134
00:06:20,560 --> 00:06:22,720
to build a more complex path,

135
00:06:22,720 --> 00:06:25,160
which starts at the project directory

136
00:06:25,160 --> 00:06:27,580
but then dives into the data folder,

137
00:06:27,580 --> 00:06:29,460
hence I add data as a string

138
00:06:29,460 --> 00:06:31,020
as a second argument.

139
00:06:31,020 --> 00:06:35,470
And then opens the users.json file.

140
00:06:35,470 --> 00:06:39,713
So users.json is the last argument here.

141
00:06:40,790 --> 00:06:43,230
And that constructs now a path

142
00:06:43,230 --> 00:06:46,540
that works cross platform on all operating systems

143
00:06:46,540 --> 00:06:48,500
to that file.

144
00:06:48,500 --> 00:06:52,873
And to writeFileSync, I'll now pass this filePath.

145
00:06:54,460 --> 00:06:55,790
Now, that's part one.

146
00:06:55,790 --> 00:06:58,730
That tells the file system package

147
00:06:58,730 --> 00:07:02,173
where the file is into which it should write.

148
00:07:03,220 --> 00:07:06,070
But we also have to define the data

149
00:07:06,070 --> 00:07:08,780
that should be written into that file.

150
00:07:08,780 --> 00:07:12,690
And that should be the existing list in that file

151
00:07:12,690 --> 00:07:16,403
plus the username we entered here.

152
00:07:17,540 --> 00:07:19,560
So therefore, we actually, first of all,

153
00:07:19,560 --> 00:07:21,840
need to read that file

154
00:07:21,840 --> 00:07:25,320
so that we can extract existing data out of it.

155
00:07:25,320 --> 00:07:28,870
Then we need to add userName to that existing data,

156
00:07:28,870 --> 00:07:32,763
and then write the updated existing data back into the file.

157
00:07:33,930 --> 00:07:36,460
Hence, actually before writing the file,

158
00:07:36,460 --> 00:07:39,700
I will use the fs package to read a file,

159
00:07:39,700 --> 00:07:42,830
again readFileSync is the correct method here.

160
00:07:42,830 --> 00:07:46,513
And I wanna read the file in that filePath.

161
00:07:48,417 --> 00:07:50,370
Here we don't need any extra argument.

162
00:07:50,370 --> 00:07:55,370
Instead we can now store the fileData in a new constant.

163
00:07:56,490 --> 00:07:59,700
And that will be the raw data read from that file.

164
00:07:59,700 --> 00:08:02,640
And that will not be a JavaScript object or array,

165
00:08:02,640 --> 00:08:07,030
instead, it will be the file content interpreted as text.

166
00:08:07,030 --> 00:08:09,730
So even if it looks like an array to us humans,

167
00:08:09,730 --> 00:08:13,363
it will be treated as text that contains square brackets.

168
00:08:14,550 --> 00:08:17,090
So to work with it, we need to transform it,

169
00:08:17,090 --> 00:08:20,935
and for that, I'll add another constant,

170
00:08:20,935 --> 00:08:25,640
existingUsers, which should be my parsed file data

171
00:08:25,640 --> 00:08:27,470
so that text content,

172
00:08:27,470 --> 00:08:31,050
which follows the JSON format actually translated

173
00:08:31,050 --> 00:08:33,633
into a JavaScript object or array.

174
00:08:34,669 --> 00:08:39,230
And NodeJS has a built-in helper object

175
00:08:39,230 --> 00:08:40,970
that offers us methods

176
00:08:40,970 --> 00:08:43,690
that help us with that transformation.

177
00:08:43,690 --> 00:08:47,883
And that's the JSON object, all uppercase.

178
00:08:49,000 --> 00:08:53,120
This object has two methods, parse and stringify,

179
00:08:53,120 --> 00:08:55,210
and parse is the method which we need

180
00:08:55,210 --> 00:08:57,410
if we wanna translate some text

181
00:08:57,410 --> 00:08:59,880
that contains data in the JSON format

182
00:08:59,880 --> 00:09:04,000
into a raw JavaScript object or array.

183
00:09:04,000 --> 00:09:06,700
And here, I wanna parse the fileData

184
00:09:06,700 --> 00:09:09,903
so that text data which we read from the file.

185
00:09:10,960 --> 00:09:12,560
With that, we're reading that data

186
00:09:12,560 --> 00:09:15,310
and we're translating it into a JavaScript array

187
00:09:15,310 --> 00:09:16,623
with which we can work.

188
00:09:18,080 --> 00:09:19,270
And then as a next step,

189
00:09:19,270 --> 00:09:21,710
we can use the existingUsers array,

190
00:09:21,710 --> 00:09:25,403
and actually add our username to that list.

191
00:09:26,455 --> 00:09:29,570
And we can do that with the push method.

192
00:09:29,570 --> 00:09:31,860
The push method is a default method,

193
00:09:31,860 --> 00:09:35,140
which we can call on any array in JavaScript,

194
00:09:35,140 --> 00:09:39,060
which allows us to add a new item to that array.

195
00:09:39,060 --> 00:09:42,593
So which appends a new item at the end of the array.

196
00:09:43,520 --> 00:09:47,680
And here I wanna push userName into existingUsers.

197
00:09:48,890 --> 00:09:52,393
So that updates existingUsers by adding a new item.

198
00:09:53,280 --> 00:09:55,570
And if you wonder why we can use const

199
00:09:55,570 --> 00:09:57,210
if we change this value,

200
00:09:57,210 --> 00:10:00,690
then the answer is that we do change the underlying value

201
00:10:00,690 --> 00:10:02,980
in memory but we never assign

202
00:10:02,980 --> 00:10:05,790
a brand new value to existingUsers.

203
00:10:05,790 --> 00:10:06,850
We would only do that

204
00:10:06,850 --> 00:10:09,660
if we use the equal sign operator again.

205
00:10:09,660 --> 00:10:11,660
If I try to assign a new empty array,

206
00:10:11,660 --> 00:10:13,670
that would be invalid.

207
00:10:13,670 --> 00:10:16,170
If I edit the existing array in memory,

208
00:10:16,170 --> 00:10:17,580
that is allowed.

209
00:10:17,580 --> 00:10:18,690
It's a bit more complex

210
00:10:18,690 --> 00:10:21,430
and a bit more advanced JavaScript knowledge here

211
00:10:21,430 --> 00:10:23,333
but it is something worth mentioning.

212
00:10:24,330 --> 00:10:26,470
This code, at the end, should work,

213
00:10:26,470 --> 00:10:29,430
and should add our user to that parsed data

214
00:10:29,430 --> 00:10:30,943
which we got from the file.

215
00:10:31,780 --> 00:10:34,320
Now, this alone will not update the file though

216
00:10:34,320 --> 00:10:36,370
because we just read data from it

217
00:10:36,370 --> 00:10:39,973
and then translated it into JavaScript objects or arrays.

218
00:10:40,870 --> 00:10:45,040
Now, to save that updated data back into the file,

219
00:10:45,040 --> 00:10:47,530
we now need to work with existing users

220
00:10:47,530 --> 00:10:50,120
to which we pushed this new userName

221
00:10:50,120 --> 00:10:53,930
and save that back into the file with writeFileSync.

222
00:10:55,200 --> 00:11:00,200
However, just as readFileSync returned just some raw text,

223
00:11:01,469 --> 00:11:05,560
writeFileSync wants some raw text.

224
00:11:05,560 --> 00:11:09,320
So if I try to pass existingUsers here,

225
00:11:09,320 --> 00:11:12,350
that would fail because that's not raw text,

226
00:11:12,350 --> 00:11:15,430
instead, that will be a JavaScript array.

227
00:11:15,430 --> 00:11:17,993
And that is not something we can store like that.

228
00:11:18,920 --> 00:11:21,150
Instead, we need to translate it back

229
00:11:21,150 --> 00:11:24,213
and we can do this by again using JSON,

230
00:11:24,213 --> 00:11:28,223
this helper object, and now the stringify method.

231
00:11:29,130 --> 00:11:32,450
To stringify, we can pass JavaScript values,

232
00:11:32,450 --> 00:11:35,450
like objects or arrays or numbers,

233
00:11:35,450 --> 00:11:38,040
and it will translate that into text,

234
00:11:38,040 --> 00:11:41,543
into raw text that follows the JSON format.

235
00:11:42,520 --> 00:11:43,970
So here to stringify,

236
00:11:43,970 --> 00:11:45,920
we can pass existingUsers,

237
00:11:45,920 --> 00:11:47,670
and now that will overall

238
00:11:47,670 --> 00:11:50,430
then save the updated existingUsers

239
00:11:50,430 --> 00:11:52,823
as text back into that file.

240
00:11:55,240 --> 00:11:57,220
Now, that was a lot of work.

241
00:11:57,220 --> 00:12:00,220
I hope the individual steps are clear.

242
00:12:00,220 --> 00:12:02,810
Let's now see whether that works.

243
00:12:02,810 --> 00:12:05,310
For that, we need to save that file,

244
00:12:05,310 --> 00:12:08,430
and then quit the existing running server,

245
00:12:08,430 --> 00:12:09,500
if you have one.

246
00:12:09,500 --> 00:12:11,230
And rerun our server

247
00:12:11,230 --> 00:12:14,580
by again executing app.js with node again.

248
00:12:14,580 --> 00:12:17,085
And then here I'll reload this page

249
00:12:17,085 --> 00:12:21,663
and again add Max Schwarzmueller as a name.

250
00:12:22,510 --> 00:12:23,410
That seems to work.

251
00:12:23,410 --> 00:12:25,120
We got no error here.

252
00:12:25,120 --> 00:12:26,980
And if I now go back here

253
00:12:26,980 --> 00:12:29,943
and open users.json, we see that name here.

254
00:12:31,580 --> 00:12:35,100
And if I now manually go back to the starting page

255
00:12:35,100 --> 00:12:37,003
by erasing that path here,

256
00:12:37,920 --> 00:12:42,900
and I add Manuel and click Submit,

257
00:12:42,900 --> 00:12:46,260
we also should see Manuel here.

258
00:12:46,260 --> 00:12:48,080
So that is being updated.

259
00:12:48,080 --> 00:12:51,180
The old data is preserved, the new name was added

260
00:12:51,180 --> 00:12:54,840
and that's how we can, for example, store data

261
00:12:54,840 --> 00:12:56,083
into a file.

262
00:12:57,070 --> 00:12:59,470
And of course, if we had a portfolio page

263
00:12:59,470 --> 00:13:01,430
with a contact me page

264
00:13:01,430 --> 00:13:04,920
where users can fill out a form to send us a message,

265
00:13:04,920 --> 00:13:08,350
we could be storing these user messages in files

266
00:13:08,350 --> 00:13:11,183
with an approach similar to what we do here.

267
00:13:12,380 --> 00:13:15,840
But here, that's not the end of what I wanna do.

268
00:13:15,840 --> 00:13:19,260
Instead, I now also wanna add a new path,

269
00:13:19,260 --> 00:13:22,110
which we can access with a get request

270
00:13:22,110 --> 00:13:24,310
where we then extract all the data

271
00:13:24,310 --> 00:13:26,760
that's stored in that file,

272
00:13:26,760 --> 00:13:31,610
and where we then send back some HTML content

273
00:13:31,610 --> 00:13:35,423
with a list of all these stored usernames.

274
00:13:36,390 --> 00:13:37,840
If you're feeling like it,

275
00:13:37,840 --> 00:13:40,010
definitely try it on your own first.

276
00:13:40,010 --> 00:13:42,883
In the next lecture, we'll implement it together.

