1
00:00:02,070 --> 00:00:03,450
So, let's continue working

2
00:00:03,450 --> 00:00:06,830
on the back end of authentication

3
00:00:06,830 --> 00:00:07,663
and for this,

4
00:00:07,663 --> 00:00:09,360
back here in our code,

5
00:00:09,360 --> 00:00:11,410
we of course wanna start

6
00:00:11,410 --> 00:00:14,220
by taking a look at the auth.controller,

7
00:00:14,220 --> 00:00:16,730
here we have to get signup function

8
00:00:16,730 --> 00:00:18,730
for serving that signup page,

9
00:00:18,730 --> 00:00:20,140
but of course in order to handle

10
00:00:20,140 --> 00:00:21,850
the submission of this form,

11
00:00:21,850 --> 00:00:24,360
we now also wanna add a new function,

12
00:00:24,360 --> 00:00:25,810
maybe right below it

13
00:00:25,810 --> 00:00:28,570
though the exact position doesn't matter,

14
00:00:28,570 --> 00:00:31,310
which could be called signup,

15
00:00:31,310 --> 00:00:32,240
the name is up to you

16
00:00:32,240 --> 00:00:34,990
but you typically wanna describe what's happening

17
00:00:34,990 --> 00:00:36,360
when this function is called

18
00:00:36,360 --> 00:00:37,840
and this should be a function,

19
00:00:37,840 --> 00:00:41,170
a controller action that will be executed

20
00:00:41,170 --> 00:00:42,800
when a user is created,

21
00:00:42,800 --> 00:00:44,163
when a user signs up.

22
00:00:45,630 --> 00:00:47,610
Here of course we still get request

23
00:00:47,610 --> 00:00:50,340
and response because we still have a middleware

24
00:00:50,340 --> 00:00:52,350
function here in the end

25
00:00:52,350 --> 00:00:55,110
and I wanna expose that outside of this file,

26
00:00:55,110 --> 00:00:58,870
so I'll make it available under a key named signup

27
00:00:58,870 --> 00:01:00,753
in my exported object.

28
00:01:01,730 --> 00:01:04,099
Now we come back to this function as second,

29
00:01:04,099 --> 00:01:05,590
for the moment,

30
00:01:05,590 --> 00:01:07,020
I wanna go to my routes,

31
00:01:07,020 --> 00:01:08,560
to the auth:routes

32
00:01:08,560 --> 00:01:11,550
and add a new route here for handling this,

33
00:01:11,550 --> 00:01:13,760
now this will not be a get route,

34
00:01:13,760 --> 00:01:16,400
because I don't wanna handle a get request,

35
00:01:16,400 --> 00:01:18,360
instead it is quite common to use

36
00:01:18,360 --> 00:01:22,290
post requests for things like signing up users,

37
00:01:22,290 --> 00:01:26,200
basically whenever you create data on the server,

38
00:01:26,200 --> 00:01:28,890
whenever you manipulate data on the server,

39
00:01:28,890 --> 00:01:30,870
you wanna use a post request

40
00:01:30,870 --> 00:01:32,483
instead of a get request,

41
00:01:33,470 --> 00:01:34,670
so therefore you're all

42
00:01:34,670 --> 00:01:36,670
to find a post route,

43
00:01:36,670 --> 00:01:39,540
the path can still be signup though

44
00:01:39,540 --> 00:01:41,200
and it's okay to have two routes

45
00:01:41,200 --> 00:01:42,540
with the same path,

46
00:01:42,540 --> 00:01:46,190
as long as they have different HTTP methods they handle

47
00:01:47,560 --> 00:01:50,580
and here I then point at auth controller signup,

48
00:01:50,580 --> 00:01:53,140
which is this newly added function I added

49
00:01:53,140 --> 00:01:54,513
a couple of seconds ago.

50
00:01:56,150 --> 00:01:57,780
Now, of course we need to ensure

51
00:01:57,780 --> 00:02:00,460
that such a post request to /signup

52
00:02:00,460 --> 00:02:03,020
is being sent when the form is submitted

53
00:02:03,020 --> 00:02:06,110
and therefore in our signup.ejs file

54
00:02:06,110 --> 00:02:07,560
where we have the form,

55
00:02:07,560 --> 00:02:09,180
we now need to set the action

56
00:02:09,180 --> 00:02:11,360
and method of that form,

57
00:02:11,360 --> 00:02:13,600
because with the action we control

58
00:02:13,600 --> 00:02:16,170
where a request is sent to,

59
00:02:16,170 --> 00:02:18,070
automatically by the browser,

60
00:02:18,070 --> 00:02:20,670
with method we define which kind

61
00:02:20,670 --> 00:02:22,053
of request is sent,

62
00:02:23,140 --> 00:02:25,900
now the where is /signup

63
00:02:25,900 --> 00:02:27,880
and this ensures that we simply target

64
00:02:27,880 --> 00:02:30,013
our current domain/signup,

65
00:02:31,080 --> 00:02:35,000
the method for forms has to be get or post

66
00:02:35,000 --> 00:02:37,100
and as mentioned a couple of seconds ago,

67
00:02:37,100 --> 00:02:40,120
we typically wanna go for post,

68
00:02:40,120 --> 00:02:43,240
this also has the advantage that post requests

69
00:02:43,240 --> 00:02:44,910
unlike get requests

70
00:02:44,910 --> 00:02:46,730
can have a post body,

71
00:02:46,730 --> 00:02:48,120
a request body,

72
00:02:48,120 --> 00:02:49,940
which can contain extra data,

73
00:02:49,940 --> 00:02:51,090
which you wanna submit,

74
00:02:51,970 --> 00:02:54,950
with get requests we can also submit data

75
00:02:54,950 --> 00:02:57,090
with help of query parameters

76
00:02:57,090 --> 00:02:58,910
as you saw before in the course,

77
00:02:58,910 --> 00:03:00,220
but this is less common

78
00:03:00,220 --> 00:03:01,860
and simply not recommended

79
00:03:01,860 --> 00:03:05,040
when you are about to store data on the back end,

80
00:03:05,040 --> 00:03:06,693
so post it is.

81
00:03:08,600 --> 00:03:11,380
Now, with that this signup.ejs file

82
00:03:11,380 --> 00:03:12,860
is properly configured,

83
00:03:12,860 --> 00:03:14,430
the route was added,

84
00:03:14,430 --> 00:03:18,010
now we just have to work on that controller

85
00:03:18,010 --> 00:03:19,630
and in this controller function,

86
00:03:19,630 --> 00:03:21,360
the signup function,

87
00:03:21,360 --> 00:03:23,360
I now of course wanna in the end

88
00:03:23,360 --> 00:03:26,340
validate all the incoming user data,

89
00:03:26,340 --> 00:03:27,800
see if it's correct

90
00:03:27,800 --> 00:03:31,260
and if we maybe already have a user with that email,

91
00:03:31,260 --> 00:03:34,120
and ultimately if we made it through

92
00:03:34,120 --> 00:03:35,490
all the validation,

93
00:03:35,490 --> 00:03:36,950
I wanna create a user

94
00:03:36,950 --> 00:03:39,610
and store that user in that database,

95
00:03:39,610 --> 00:03:41,580
and that's the keyword,

96
00:03:41,580 --> 00:03:46,020
database, before we start writing any logic here,

97
00:03:46,020 --> 00:03:48,610
we wanna make sure that we're able to connect

98
00:03:48,610 --> 00:03:50,170
to a database

99
00:03:50,170 --> 00:03:53,370
and you can of course build this kind of website

100
00:03:53,370 --> 00:03:57,450
with both a SQL based database like MySQL

101
00:03:57,450 --> 00:04:01,060
or a no sequel database like MongoDB,

102
00:04:01,060 --> 00:04:03,250
I will go for MongoDB here

103
00:04:03,250 --> 00:04:07,440
because it's a bit closer to JavaScript

104
00:04:07,440 --> 00:04:08,710
syntax wise,

105
00:04:08,710 --> 00:04:11,080
which can make it a bit easier to work with

106
00:04:11,080 --> 00:04:12,640
and we've been working with it

107
00:04:12,640 --> 00:04:14,120
a lot throughout the course,

108
00:04:14,120 --> 00:04:17,190
so we probably got more practice with it,

109
00:04:17,190 --> 00:04:20,149
nonetheless, definitely feel free to also build

110
00:04:20,149 --> 00:04:23,207
a version of this project where you use SQL

111
00:04:23,207 --> 00:04:24,900
and MySQL instead,

112
00:04:24,900 --> 00:04:26,113
both will work.

113
00:04:27,010 --> 00:04:29,360
Now, you wanna ensure that you got MongoDB

114
00:04:29,360 --> 00:04:31,250
installed to continue

115
00:04:31,250 --> 00:04:34,690
and of course we did install it earlier in the course,

116
00:04:34,690 --> 00:04:36,720
if you skipped those sections,

117
00:04:36,720 --> 00:04:39,070
I do recommend that you go through them,

118
00:04:39,070 --> 00:04:41,980
you wanna install the community server in the end,

119
00:04:41,980 --> 00:04:44,300
so even if you don't go through these sections,

120
00:04:44,300 --> 00:04:46,160
you can of course also install it

121
00:04:46,160 --> 00:04:48,020
with help of the official docs

122
00:04:48,020 --> 00:04:50,910
where you can also learn how to install

123
00:04:50,910 --> 00:04:53,930
MongoDB on different operating systems,

124
00:04:53,930 --> 00:04:55,980
it's the Community Edition which we need,

125
00:04:57,150 --> 00:04:58,440
once you did install it,

126
00:04:58,440 --> 00:05:00,220
you also need to start it,

127
00:05:00,220 --> 00:05:02,300
you learned about that earlier in the course

128
00:05:02,300 --> 00:05:04,730
and you'll also find instructions on this here

129
00:05:04,730 --> 00:05:05,920
in the official docs

130
00:05:06,850 --> 00:05:08,520
and once you started it,

131
00:05:08,520 --> 00:05:11,520
here I have it running in a separate terminal window,

132
00:05:11,520 --> 00:05:14,000
we are ready to connect to it,

133
00:05:14,000 --> 00:05:15,490
now for connecting to it

134
00:05:15,490 --> 00:05:18,500
and for managing a pool of connections,

135
00:05:18,500 --> 00:05:21,520
I will create a separate file

136
00:05:21,520 --> 00:05:23,070
and actually a separate folder

137
00:05:23,070 --> 00:05:26,730
which we'll name data or database,

138
00:05:26,730 --> 00:05:29,600
in which I'll add a database.js file

139
00:05:29,600 --> 00:05:31,550
and this file will hold the logic

140
00:05:31,550 --> 00:05:33,383
for connecting to MongoDB,

141
00:05:34,250 --> 00:05:36,300
however I still don't wanna write

142
00:05:36,300 --> 00:05:37,840
all the logic on my own,

143
00:05:37,840 --> 00:05:40,720
I instead will install a third-party package

144
00:05:40,720 --> 00:05:43,120
which we have also used a lot in this course,

145
00:05:43,120 --> 00:05:44,930
the MongoDB package,

146
00:05:44,930 --> 00:05:46,760
which helps us with establishing

147
00:05:46,760 --> 00:05:48,920
and managing that connection,

148
00:05:48,920 --> 00:05:51,040
so npm installed MongoDB

149
00:05:52,470 --> 00:05:54,150
and once that is installed,

150
00:05:54,150 --> 00:05:57,110
in this newly added database.js file,

151
00:05:57,110 --> 00:06:01,720
we can import MongoDB by requiring it in there

152
00:06:01,720 --> 00:06:03,730
and this MongoDB package will give us

153
00:06:03,730 --> 00:06:05,510
a lot of utility methods

154
00:06:05,510 --> 00:06:08,163
that make working with a database easier,

155
00:06:09,000 --> 00:06:11,910
because here with that required now,

156
00:06:11,910 --> 00:06:13,200
as a next step,

157
00:06:13,200 --> 00:06:17,160
I will create a MongoClient by using

158
00:06:17,160 --> 00:06:20,670
mongodb.mongoclient, whoops.

159
00:06:20,670 --> 00:06:22,590
MongoClient like this

160
00:06:23,870 --> 00:06:26,410
and then we can use this MongoClient

161
00:06:26,410 --> 00:06:30,490
to call the connect static method on it,

162
00:06:30,490 --> 00:06:32,900
so we don't need to instantiate MongoClient,

163
00:06:32,900 --> 00:06:35,390
we can call connect on it like this

164
00:06:35,390 --> 00:06:40,390
and connect then takes the URL to our database,

165
00:06:41,120 --> 00:06:44,890
and with a locally installed MongoDB database server,

166
00:06:44,890 --> 00:06:48,860
that is localhost:27017,

167
00:06:48,860 --> 00:06:51,220
that's the default port occupied

168
00:06:51,220 --> 00:06:53,073
by the MongoDB server.

169
00:06:54,850 --> 00:06:57,020
Now, connect returns a promise

170
00:06:57,020 --> 00:06:58,670
and you learned about promises,

171
00:06:58,670 --> 00:07:01,310
these are objects which will eventually

172
00:07:01,310 --> 00:07:03,250
resolve to a certain value

173
00:07:03,250 --> 00:07:05,910
and they are often used in situations

174
00:07:05,910 --> 00:07:08,870
where you have an asynchronous operation,

175
00:07:08,870 --> 00:07:11,740
so an operation which may take a bit longer

176
00:07:11,740 --> 00:07:13,890
and which therefore runs side by side

177
00:07:13,890 --> 00:07:14,910
with your AVer code

178
00:07:14,910 --> 00:07:17,400
and which eventually then completes,

179
00:07:17,400 --> 00:07:19,600
and we can handle such promises

180
00:07:19,600 --> 00:07:21,560
with help of the then method

181
00:07:21,560 --> 00:07:24,470
which we can call on the promise object,

182
00:07:24,470 --> 00:07:28,103
or a bit more convenient with async await,

183
00:07:29,040 --> 00:07:31,100
for this we just need a separate function,

184
00:07:31,100 --> 00:07:33,490
which I would need anyways here though,

185
00:07:33,490 --> 00:07:36,470
which could be called connectToDatabase

186
00:07:38,070 --> 00:07:40,210
and this function can be decorated

187
00:07:40,210 --> 00:07:41,923
with the async keyword,

188
00:07:42,920 --> 00:07:45,460
this then unlocks the await keyword

189
00:07:45,460 --> 00:07:47,420
inside of this function

190
00:07:47,420 --> 00:07:49,803
and now if I call MongoClient.connect

191
00:07:49,803 --> 00:07:51,200
instead of this function,

192
00:07:51,200 --> 00:07:52,540
we can await this

193
00:07:53,920 --> 00:07:56,770
and what we'll get back is a client object

194
00:07:56,770 --> 00:07:59,410
which has internal information

195
00:07:59,410 --> 00:08:01,603
about the established connection,

196
00:08:03,140 --> 00:08:05,470
now I want to use this client

197
00:08:05,470 --> 00:08:08,710
in various places of my project here

198
00:08:08,710 --> 00:08:09,543
and hence,

199
00:08:09,543 --> 00:08:11,640
I'll add a database variable,

200
00:08:11,640 --> 00:08:13,910
which initially is undefined

201
00:08:13,910 --> 00:08:15,200
and in the end,

202
00:08:15,200 --> 00:08:16,830
in this database variable,

203
00:08:16,830 --> 00:08:19,083
I'll store client.db,

204
00:08:20,700 --> 00:08:21,940
which is a built in method,

205
00:08:21,940 --> 00:08:24,950
which we can call on this client object

206
00:08:24,950 --> 00:08:27,280
to connect to a certain database

207
00:08:27,280 --> 00:08:29,010
and here I'll choose online-shop

208
00:08:29,010 --> 00:08:30,500
as a database name,

209
00:08:30,500 --> 00:08:32,210
as we learned in this course

210
00:08:32,210 --> 00:08:34,110
when working with MongoDB,

211
00:08:34,110 --> 00:08:37,470
you don't have to create databases ahead of time,

212
00:08:37,470 --> 00:08:40,620
instead you can simply use any database of your choice

213
00:08:40,620 --> 00:08:42,480
and it will be created for you

214
00:08:42,480 --> 00:08:45,920
the first time you enter data if it doesn't exist yet

215
00:08:46,890 --> 00:08:50,200
and it's then the connection to this concrete database

216
00:08:50,200 --> 00:08:52,820
which is stored in this database variable

217
00:08:53,820 --> 00:08:55,440
and I'm using this variable

218
00:08:55,440 --> 00:08:57,456
because I'll add a second function,

219
00:08:57,456 --> 00:09:02,456
getDb where I actually will check

220
00:09:02,780 --> 00:09:05,800
if we maybe don't have a database yet,

221
00:09:05,800 --> 00:09:07,190
in which case,

222
00:09:07,190 --> 00:09:10,950
I'll generate a custom error,

223
00:09:10,950 --> 00:09:12,740
we can throw section error

224
00:09:12,740 --> 00:09:14,240
with the throw keyword

225
00:09:14,240 --> 00:09:16,510
and that will crash the application then

226
00:09:16,510 --> 00:09:18,730
or at least generate an error

227
00:09:18,730 --> 00:09:20,920
which we can handle in some other place,

228
00:09:20,920 --> 00:09:22,900
if we try to access the database

229
00:09:22,900 --> 00:09:25,340
without connecting to it first,

230
00:09:25,340 --> 00:09:26,670
which shouldn't happen here

231
00:09:26,670 --> 00:09:28,110
but which could happen

232
00:09:28,110 --> 00:09:31,230
and I'll create a new error object

233
00:09:31,230 --> 00:09:33,070
with new error,

234
00:09:33,070 --> 00:09:35,690
using the built in error clause,

235
00:09:35,690 --> 00:09:39,610
or constructor function which is built into JavaScript

236
00:09:39,610 --> 00:09:41,610
to generate an error object

237
00:09:41,610 --> 00:09:45,620
and to then throw this generated error object,

238
00:09:45,620 --> 00:09:48,470
and to this error constructor function,

239
00:09:48,470 --> 00:09:51,330
you can pass a error message string like,

240
00:09:51,330 --> 00:09:54,510
'You must connect first!'

241
00:09:54,510 --> 00:09:56,140
So, now that's an error I will throw

242
00:09:56,140 --> 00:09:58,460
if we try to get access to the database

243
00:09:58,460 --> 00:10:01,120
without establishing the connection first,

244
00:10:01,120 --> 00:10:02,980
if we make it past the safe check,

245
00:10:02,980 --> 00:10:04,530
which we normally should,

246
00:10:04,530 --> 00:10:07,750
I will return a handle to that database

247
00:10:09,570 --> 00:10:13,060
and then ultimately I want access to these functions

248
00:10:13,060 --> 00:10:15,190
from outside this file,

249
00:10:15,190 --> 00:10:19,030
so I will export an object,

250
00:10:19,030 --> 00:10:22,700
an object which has a pointer at connectToDatabase

251
00:10:23,960 --> 00:10:26,840
using connectToDatabase as a key

252
00:10:27,730 --> 00:10:32,730
and which has a pointer to getDb using getDb as a key,

253
00:10:35,340 --> 00:10:38,203
so that's my database.js file.

254
00:10:39,880 --> 00:10:43,900
This database.js file will now be used

255
00:10:43,900 --> 00:10:46,000
in my app.js file

256
00:10:46,000 --> 00:10:48,267
because there I wanna establish a connection

257
00:10:48,267 --> 00:10:53,090
to the database right when I'm starting my web server

258
00:10:53,090 --> 00:10:55,310
and I don't wanna start my web server

259
00:10:55,310 --> 00:10:58,393
if establishing that database connection failed,

260
00:10:59,470 --> 00:11:02,440
so here in app.js we can start by importing

261
00:11:02,440 --> 00:11:05,180
this database object,

262
00:11:05,180 --> 00:11:09,350
by requiring ./data/database

263
00:11:12,490 --> 00:11:13,660
and then here at the bottom

264
00:11:13,660 --> 00:11:15,403
where I call app.listen,

265
00:11:16,560 --> 00:11:21,360
I will now simply call db.connectToDatabase

266
00:11:23,410 --> 00:11:25,970
and this then yields a promise

267
00:11:25,970 --> 00:11:29,113
simply because in database.js,

268
00:11:30,242 --> 00:11:32,880
connectToDatabase is an async function

269
00:11:32,880 --> 00:11:35,410
and any function decorated with async

270
00:11:35,410 --> 00:11:38,950
will automatically always yield a promise,

271
00:11:38,950 --> 00:11:41,650
even if you don't return a promise yourself,

272
00:11:41,650 --> 00:11:43,890
I don't have any return statement in there,

273
00:11:43,890 --> 00:11:46,580
nonetheless, async functions will always

274
00:11:46,580 --> 00:11:48,780
return a promise automatically

275
00:11:48,780 --> 00:11:50,610
and therefore in app.js,

276
00:11:50,610 --> 00:11:52,500
where I call connectToDatabase,

277
00:11:52,500 --> 00:11:54,370
this will yield a promise

278
00:11:54,370 --> 00:11:56,680
and then here we can add then

279
00:11:56,680 --> 00:12:00,350
to execute code if that promise succeeded

280
00:12:00,350 --> 00:12:03,620
or a catch if that promise failed

281
00:12:03,620 --> 00:12:05,570
if we had an error in there for example

282
00:12:07,030 --> 00:12:09,120
and we could get an error if connecting

283
00:12:09,120 --> 00:12:10,523
to the database fails.

284
00:12:11,610 --> 00:12:12,900
Now, in that error case,

285
00:12:12,900 --> 00:12:15,330
I'll define an anonymous function

286
00:12:15,330 --> 00:12:17,330
which gets that error object,

287
00:12:17,330 --> 00:12:20,740
which is generated automatically by the MongoDB package

288
00:12:20,740 --> 00:12:22,880
if establishing the connection failed

289
00:12:23,930 --> 00:12:24,830
and then I'll just

290
00:12:24,830 --> 00:12:29,830
console.log('Failed to connect to the database!')

291
00:12:31,189 --> 00:12:35,180
and after that I'll also console log the error object

292
00:12:35,180 --> 00:12:38,573
so that we can see more details about the error as well.

293
00:12:40,640 --> 00:12:43,310
Now, in the then case that we succeeded,

294
00:12:43,310 --> 00:12:47,750
here I actually will also define an anonymous function

295
00:12:47,750 --> 00:12:50,967
and in here I just want to call app.listen(3000),

296
00:12:51,820 --> 00:12:53,310
so this code down there

297
00:12:53,310 --> 00:12:55,320
to only startup the web server

298
00:12:55,320 --> 00:12:57,950
and start listening on port 3000

299
00:12:57,950 --> 00:13:00,453
if we connected to the database successfully,

300
00:13:01,850 --> 00:13:05,080
with that we should be establishing a database connection

301
00:13:05,080 --> 00:13:07,150
whenever we start this server,

302
00:13:07,150 --> 00:13:09,860
so now since I shutdown the server before anyways

303
00:13:09,860 --> 00:13:13,000
in order to install the MongoDB package,

304
00:13:13,000 --> 00:13:15,520
we can restart it with npm start

305
00:13:15,520 --> 00:13:18,453
and it crashes here for me,

306
00:13:19,570 --> 00:13:21,130
invalid connection spring

307
00:13:21,130 --> 00:13:24,670
and yes the reason is a mistake

308
00:13:24,670 --> 00:13:28,130
in database.js in this URL,

309
00:13:28,130 --> 00:13:30,820
the correct URL to a locally installed

310
00:13:30,820 --> 00:13:34,920
MongoDB database is localhost:27017,

311
00:13:34,920 --> 00:13:39,920
but we have to prefix this with mongodb://,

312
00:13:40,640 --> 00:13:42,700
that's the actual URL,

313
00:13:42,700 --> 00:13:44,653
the MongoDB package wants,

314
00:13:46,460 --> 00:13:48,200
so if we now save this,

315
00:13:48,200 --> 00:13:49,580
this now restarts

316
00:13:49,580 --> 00:13:52,110
and now we have that running server

317
00:13:52,110 --> 00:13:54,133
which is connected to a database.

