﻿1
00:00:01,090 --> 00:00:04,280
‫Let's now actually configure Multer to our needs.

2
00:00:04,280 --> 00:00:07,380
‫First giving images a better filename,

3
00:00:07,380 --> 00:00:09,990
‫then second allowing only image files

4
00:00:09,990 --> 00:00:12,193
‫to be uploaded onto our server.

5
00:00:13,880 --> 00:00:15,640
‫And to start, let's actually move

6
00:00:15,640 --> 00:00:17,210
‫all the Multer-related stuff

7
00:00:17,210 --> 00:00:19,563
‫from this router to the controller.

8
00:00:21,910 --> 00:00:23,633
‫So let's cut this here,

9
00:00:24,600 --> 00:00:27,220
‫and I'm gonna put it right here at the end,

10
00:00:27,220 --> 00:00:30,570
‫or actually at the top, all right?

11
00:00:30,570 --> 00:00:32,710
‫So everything related to Multer,

12
00:00:32,710 --> 00:00:35,263
‫we're going to put it right here at the top.

13
00:00:36,400 --> 00:00:41,400
‫Then we also need of course to import this Multer package.

14
00:00:44,940 --> 00:00:48,503
‫And now we also need to create a middleware with this.

15
00:00:53,970 --> 00:00:56,393
‫So exports.uploadUserPhoto

16
00:01:01,540 --> 00:01:03,253
‫will be equal to this.

17
00:01:05,176 --> 00:01:07,890
‫All right, and so we still have a middleware function,

18
00:01:07,890 --> 00:01:12,890
‫but now it's got its own easier to use name, all right?

19
00:01:13,950 --> 00:01:16,880
‫And so here, userController.uploadPhoto, all right?

20
00:01:20,460 --> 00:01:22,200
‫So that looks much nicer,

21
00:01:22,200 --> 00:01:23,610
‫and of course it makes sense

22
00:01:23,610 --> 00:01:25,950
‫that this code is in the controller.

23
00:01:25,950 --> 00:01:28,010
‫And so now this is nice and clean,

24
00:01:28,010 --> 00:01:30,790
‫and we can actually close it now.

25
00:01:30,790 --> 00:01:33,260
‫Great, and so now let's actually go ahead

26
00:01:33,260 --> 00:01:36,400
‫and configure our Multer upload to our needs.

27
00:01:36,400 --> 00:01:39,640
‫And so for that we are going to create one Multer storage

28
00:01:39,640 --> 00:01:41,950
‫and one Multer filter, all right?

29
00:01:41,950 --> 00:01:45,260
‫And then we're going to use that storage and the filter

30
00:01:45,260 --> 00:01:49,513
‫to then create the upload from there, all right?

31
00:01:50,400 --> 00:01:51,603
‫So let's do that here.

32
00:01:56,320 --> 00:02:01,053
‫So a multerStorage, we use multer.diskStorage.

33
00:02:03,880 --> 00:02:05,760
‫All right, and we could also choose

34
00:02:05,760 --> 00:02:08,560
‫to store the file in memory as a buffer,

35
00:02:08,560 --> 00:02:11,670
‫so that we could then use it later by other processes.

36
00:02:11,670 --> 00:02:14,050
‫And actually we're gonna do that a bit later,

37
00:02:14,050 --> 00:02:16,700
‫but for now of course we want to really store the file

38
00:02:16,700 --> 00:02:20,120
‫as it is in our file system, okay?

39
00:02:20,120 --> 00:02:23,690
‫So for disk storage we'll take a couple of options,

40
00:02:23,690 --> 00:02:25,693
‫and the first one is the destination.

41
00:02:27,900 --> 00:02:31,390
‫But now we cannot simply set it to this path

42
00:02:31,390 --> 00:02:32,850
‫like we did before.

43
00:02:32,850 --> 00:02:35,760
‫No, this is a bit more complex, all right?

44
00:02:35,760 --> 00:02:39,550
‫And so really this destination here is a callback function

45
00:02:39,550 --> 00:02:41,400
‫which goes like this.

46
00:02:41,400 --> 00:02:45,610
‫So this callback function has access to the current request,

47
00:02:45,610 --> 00:02:47,750
‫to the currently uploaded file,

48
00:02:47,750 --> 00:02:49,820
‫and also to a callback function.

49
00:02:49,820 --> 00:02:51,330
‫And this callback function is a bit

50
00:02:51,330 --> 00:02:53,720
‫like the next function in Express.

51
00:02:53,720 --> 00:02:56,810
‫But I'm calling it cb here, which stands for callback,

52
00:02:56,810 --> 00:02:58,790
‫so that it's a different name than next,

53
00:02:58,790 --> 00:03:02,000
‫because actually it doesn't come from Express, okay?

54
00:03:02,000 --> 00:03:05,070
‫But it's similar in that we can pass errors in here

55
00:03:05,070 --> 00:03:07,683
‫and other stuff, as you will see in a second.

56
00:03:10,830 --> 00:03:12,730
‫So to now define the destination,

57
00:03:12,730 --> 00:03:15,640
‫we actually need to call that callback.

58
00:03:15,640 --> 00:03:18,730
‫So callback, and then the first argument is an error

59
00:03:18,730 --> 00:03:19,820
‫if there is one.

60
00:03:19,820 --> 00:03:21,523
‫And if not, then just null.

61
00:03:22,910 --> 00:03:25,943
‫And the second argument is then the actual destination.

62
00:03:26,810 --> 00:03:28,260
‫So let's copy that from here,

63
00:03:29,180 --> 00:03:31,333
‫and paste it here.

64
00:03:32,500 --> 00:03:37,500
‫All right, and again this all looks a bit weird and complex,

65
00:03:37,820 --> 00:03:39,130
‫and let's actually take a look

66
00:03:39,130 --> 00:03:41,433
‫at the Multer documentation on GitHub.

67
00:03:48,860 --> 00:03:50,970
‫Okay, and so if you need to learn more,

68
00:03:50,970 --> 00:03:54,570
‫you can take a look at this documentation here.

69
00:03:54,570 --> 00:03:56,890
‫And as you see, with 6,000 stars,

70
00:03:56,890 --> 00:04:01,890
‫it's actually a pretty popular package.

71
00:04:02,090 --> 00:04:04,293
‫So here you can learn how to use it.

72
00:04:05,270 --> 00:04:07,090
‫But in fact what you will find here

73
00:04:07,090 --> 00:04:08,700
‫is kind of what we're gonna do

74
00:04:08,700 --> 00:04:11,283
‫throughout the next couple of lectures, okay?

75
00:04:12,290 --> 00:04:15,000
‫So this looks way more confusing

76
00:04:15,000 --> 00:04:17,350
‫than what we're going to do, all right?

77
00:04:17,350 --> 00:04:18,750
‫But you see that this is actually

78
00:04:18,750 --> 00:04:22,820
‫what we're doing currently, so we're setting the destination

79
00:04:22,820 --> 00:04:26,580
‫and next we will actually also set the filename.

80
00:04:26,580 --> 00:04:30,250
‫So let's do that, and again, if you want to learn more

81
00:04:30,250 --> 00:04:33,400
‫just take a look at that documentation.

82
00:04:33,400 --> 00:04:37,840
‫But for now I want to now set the filename property.

83
00:04:37,840 --> 00:04:41,593
‫So not that, simply filename.

84
00:04:42,610 --> 00:04:45,980
‫And again, that's a very similar callback function

85
00:04:45,980 --> 00:04:50,973
‫with a similar signature, request, file and callback.

86
00:04:54,540 --> 00:04:57,980
‫And now we want to give our files some unique filenames.

87
00:04:57,980 --> 00:04:59,380
‫And the way I'm going to do that

88
00:04:59,380 --> 00:05:04,380
‫is to call them user-userid- the current timestamp.

89
00:05:04,990 --> 00:05:07,720
‫So something like this: so user-,

90
00:05:07,720 --> 00:05:11,793
‫and then the ID which is this weird, something like this.

91
00:05:14,190 --> 00:05:16,640
‫Right, and then the current timestamp,

92
00:05:16,640 --> 00:05:19,880
‫which is going to be a huge number, something like this,

93
00:05:19,880 --> 00:05:23,490
‫and then of course the file extension, okay?

94
00:05:23,490 --> 00:05:25,730
‫And with this we can basically guarantee

95
00:05:25,730 --> 00:05:29,030
‫that there won't be two images with the same filename.

96
00:05:29,030 --> 00:05:31,290
‫If we used only the user ID,

97
00:05:31,290 --> 00:05:33,820
‫then of course multiple uploads by the same user

98
00:05:33,820 --> 00:05:36,140
‫would override the previous image.

99
00:05:36,140 --> 00:05:39,770
‫And if we only used user with the timestamp, well,

100
00:05:39,770 --> 00:05:43,210
‫then if two users were uploading an image at the same time,

101
00:05:43,210 --> 00:05:45,920
‫they would then get the exact same filename,

102
00:05:45,920 --> 00:05:47,393
‫which does not make sense.

103
00:05:48,630 --> 00:05:51,300
‫All right, so first of all,

104
00:05:51,300 --> 00:05:55,330
‫let's actually extract the filename from the uploaded file.

105
00:05:55,330 --> 00:05:57,060
‫And how do we get that?

106
00:05:57,060 --> 00:05:59,963
‫Well let's take a look at our console output here,

107
00:06:03,080 --> 00:06:06,120
‫where we had the request.file a long time ago.

108
00:06:06,120 --> 00:06:09,080
‫So here it is, so remember that this object here

109
00:06:09,080 --> 00:06:11,830
‫was request.file, and so that is exactly

110
00:06:11,830 --> 00:06:15,530
‫what this file here is, okay?

111
00:06:15,530 --> 00:06:18,260
‫And so here we have the mimetype,

112
00:06:18,260 --> 00:06:22,087
‫and so that JPEG is stored right here, okay?

113
00:06:22,087 --> 00:06:24,030
‫And so this is where we're gonna get

114
00:06:24,030 --> 00:06:25,363
‫the file extension from.

115
00:06:28,130 --> 00:06:33,130
‫So extension equals the file.mimetype,

116
00:06:35,290 --> 00:06:39,550
‫and then let's split that string by the slash,

117
00:06:39,550 --> 00:06:42,720
‫and take the second element of the resulting array.

118
00:06:42,720 --> 00:06:46,853
‫And so that will then be only this part, so only this.

119
00:06:47,780 --> 00:06:50,500
‫All right, so that is the extension.

120
00:06:50,500 --> 00:06:52,100
‫And so now just like before,

121
00:06:52,100 --> 00:06:56,760
‫we need to call the callback function with no error,

122
00:06:56,760 --> 00:06:59,423
‫and then the filename that we want to specify.

123
00:07:00,460 --> 00:07:05,460
‫So, that will be user-, then the user ID, remember?

124
00:07:06,890 --> 00:07:09,970
‫And so since we have access to the request here,

125
00:07:09,970 --> 00:07:13,913
‫that's very simple, request.user.id.

126
00:07:14,830 --> 00:07:16,620
‫And so as you know, that's the ID

127
00:07:16,620 --> 00:07:19,040
‫from the currently logged in user.

128
00:07:19,040 --> 00:07:24,040
‫Then the timestamp, so Date.now, okay,

129
00:07:25,547 --> 00:07:30,547
‫and then dot the extension that we just created, all right?

130
00:07:33,120 --> 00:07:35,410
‫So let's get rid of this comment,

131
00:07:35,410 --> 00:07:37,780
‫and so that is actually our storage.

132
00:07:37,780 --> 00:07:40,310
‫And so basically a complete definition

133
00:07:40,310 --> 00:07:42,540
‫of how we want to store our files,

134
00:07:42,540 --> 00:07:44,963
‫with the destination and the filename.

135
00:07:46,270 --> 00:07:48,833
‫Next up, let's create a Multer filter.

136
00:07:52,270 --> 00:07:53,983
‫So let's call it exactly that.

137
00:07:57,200 --> 00:08:00,370
‫And the filter in Multer is simply, again,

138
00:08:00,370 --> 00:08:04,010
‫a callback function, similar to the ones we had before,

139
00:08:04,010 --> 00:08:08,433
‫accessing the request, file, and a callback function.

140
00:08:09,850 --> 00:08:11,730
‫And in this function, the goal is basically

141
00:08:11,730 --> 00:08:14,660
‫to test if the uploaded file is an image.

142
00:08:14,660 --> 00:08:17,220
‫And if it is so, then we pass true

143
00:08:17,220 --> 00:08:19,010
‫into the callback function,

144
00:08:19,010 --> 00:08:22,110
‫and if it's not we pass false into the callback function,

145
00:08:22,110 --> 00:08:23,410
‫along with an error.

146
00:08:23,410 --> 00:08:25,810
‫Because again, we do not want to allow files

147
00:08:25,810 --> 00:08:28,020
‫to be uploaded that are not images.

148
00:08:28,020 --> 00:08:31,370
‫And so that's exactly what this filter is for.

149
00:08:31,370 --> 00:08:33,090
‫Now, if in your own application

150
00:08:33,090 --> 00:08:36,830
‫you want to upload something else, let's say CSV files,

151
00:08:36,830 --> 00:08:40,260
‫when then of course you can test for that instead of images.

152
00:08:40,260 --> 00:08:42,240
‫So all the stuff that we're doing here

153
00:08:42,240 --> 00:08:43,960
‫works not only for images,

154
00:08:43,960 --> 00:08:45,790
‫but really for all kinds of files

155
00:08:45,790 --> 00:08:48,090
‫that you want to upload, all right?

156
00:08:48,090 --> 00:08:51,610
‫Now again, in this case we are really talking about images,

157
00:08:51,610 --> 00:08:54,640
‫and so let's test if the uploaded file is an image.

158
00:08:54,640 --> 00:08:58,410
‫And for that we will once more use the mimetype,

159
00:08:58,410 --> 00:09:00,770
‫because whatever image type is uploaded,

160
00:09:00,770 --> 00:09:05,300
‫so no matter if it's a JPEG, or a PNG, or a bitmap,

161
00:09:05,300 --> 00:09:07,730
‫or a TIFF, or really anything,

162
00:09:07,730 --> 00:09:10,950
‫the mimetype will always start with image.

163
00:09:10,950 --> 00:09:13,170
‫And so now we can test for that.

164
00:09:13,170 --> 00:09:17,643
‫So if file.mimetype.startsWith,

165
00:09:21,890 --> 00:09:25,910
‫image, and so I'm not sure if we have used this one before,

166
00:09:25,910 --> 00:09:29,700
‫but it is a fairly new and very useful string method

167
00:09:29,700 --> 00:09:31,750
‫that is available in JavaScript,

168
00:09:31,750 --> 00:09:33,593
‫so in all JavaScript in general.

169
00:09:34,770 --> 00:09:38,650
‫So in case that we actually have an image, well,

170
00:09:38,650 --> 00:09:42,090
‫then again there is no error and we pass true,

171
00:09:42,090 --> 00:09:43,810
‫as I said in the beginning.

172
00:09:43,810 --> 00:09:48,810
‫But otherwise, we will then actually pass an error,

173
00:09:50,520 --> 00:09:52,080
‫and then false.

174
00:09:52,080 --> 00:09:55,320
‫So let's just put an x here, and false.

175
00:09:55,320 --> 00:09:58,910
‫So for this x here, we will now create an AppError,

176
00:09:58,910 --> 00:10:01,010
‫just like we've been doing all along.

177
00:10:01,010 --> 00:10:03,423
‫And actually we already have that here.

178
00:10:04,470 --> 00:10:07,643
‫So let's say new AppError,

179
00:10:10,522 --> 00:10:14,896
‫not an image,

180
00:10:14,896 --> 00:10:19,896
‫please upload only images, all right?

181
00:10:20,709 --> 00:10:23,459
‫And then a 400 for a bad request.

182
00:10:24,876 --> 00:10:28,875
‫Great, so we have our storage, we have our filter,

183
00:10:28,875 --> 00:10:30,567
‫now it's time to actually use them

184
00:10:30,567 --> 00:10:33,294
‫in order to create the upload.

185
00:10:33,294 --> 00:10:37,228
‫All right, so the upload will now not look like this,

186
00:10:37,228 --> 00:10:40,816
‫but instead we will pass in these variables.

187
00:10:40,816 --> 00:10:44,149
‫So in Multer we can specify the storage,

188
00:10:46,618 --> 00:10:49,368
‫and so that is our multerStorage.

189
00:10:52,118 --> 00:10:54,118
‫And then the fileFilter,

190
00:10:57,109 --> 00:11:01,276
‫which is the variable that we called multerFilter.

191
00:11:02,439 --> 00:11:04,299
‫Okay, and that's it.

192
00:11:04,299 --> 00:11:06,486
‫And of course we could've put all of this here

193
00:11:06,486 --> 00:11:10,225
‫directly into this options object here.

194
00:11:10,225 --> 00:11:12,901
‫But I usually prefer to do these outside

195
00:11:12,901 --> 00:11:17,076
‫and then simply pass the variables into an options object.

196
00:11:17,076 --> 00:11:19,351
‫So that then looks a bit cleaner.

197
00:11:19,351 --> 00:11:22,241
‫So this is a lot of steps that we need to take

198
00:11:22,241 --> 00:11:26,046
‫in order to really create our Multer middleware.

199
00:11:26,046 --> 00:11:27,953
‫But finally we then of course,

200
00:11:27,953 --> 00:11:29,770
‫just like we did in the last video,

201
00:11:29,770 --> 00:11:33,169
‫use this upload, and on that we call single,

202
00:11:33,169 --> 00:11:35,437
‫with the name of the field.

203
00:11:35,437 --> 00:11:38,688
‫So photo, and then from there we create an export,

204
00:11:38,688 --> 00:11:41,262
‫or middleware, which we actually already included

205
00:11:41,262 --> 00:11:42,880
‫into our router.

206
00:11:42,880 --> 00:11:46,845
‫So let's now delete this old kind of image

207
00:11:46,845 --> 00:11:48,845
‫that we had here before.

208
00:11:50,649 --> 00:11:52,399
‫No, that didn't work.

209
00:11:54,543 --> 00:11:57,569
‫And now let's actually test it here again.

210
00:11:57,569 --> 00:12:00,637
‫So back in Postman, we still have our name here

211
00:12:00,637 --> 00:12:03,554
‫and the Leo image, and so let's go.

212
00:12:05,556 --> 00:12:08,473
‫And we got no error, which is good.

213
00:12:10,516 --> 00:12:13,516
‫And let's see our output here again.

214
00:12:16,428 --> 00:12:19,240
‫So everything here in the beginning is the same,

215
00:12:19,240 --> 00:12:23,827
‫but then you see that our filename is actually now correct.

216
00:12:23,827 --> 00:12:26,465
‫And if you take a look here at our folder,

217
00:12:26,465 --> 00:12:28,948
‫then indeed there is our image.

218
00:12:28,948 --> 00:12:31,934
‫And so that's exactly the one that we uploaded.

219
00:12:31,934 --> 00:12:34,934
‫So that is in dev-data, images, Leo.

220
00:12:37,649 --> 00:12:41,288
‫And indeed, that is exactly the same.

221
00:12:41,288 --> 00:12:43,724
‫Great, that's awesome.

222
00:12:43,724 --> 00:12:46,615
‫Now just to test this filter here as well,

223
00:12:46,615 --> 00:12:51,615
‫let's try to upload some other file that is not an image.

224
00:12:51,974 --> 00:12:56,516
‫So let's select something else here from our dev-data,

225
00:12:56,516 --> 00:13:00,278
‫and let's say simply some JSON data.

226
00:13:00,278 --> 00:13:04,336
‫And so let's wait if we get an error here.

227
00:13:04,336 --> 00:13:06,190
‫And indeed we get one.

228
00:13:06,190 --> 00:13:09,070
‫So not an image, please upload only images.

229
00:13:09,070 --> 00:13:11,643
‫And so it means that that also works.

230
00:13:12,610 --> 00:13:16,200
‫So perfect, all of our Multer configuration

231
00:13:16,200 --> 00:13:18,540
‫now works really fine, but of course

232
00:13:18,540 --> 00:13:20,480
‫there's still one step missing.

233
00:13:20,480 --> 00:13:22,660
‫And that is to actually link the user

234
00:13:22,660 --> 00:13:25,550
‫to the newly-updated image, right?

235
00:13:25,550 --> 00:13:27,660
‫Because right now in the database,

236
00:13:27,660 --> 00:13:29,420
‫we obviously still have the path,

237
00:13:29,420 --> 00:13:31,840
‫or actually the name of the old image,

238
00:13:31,840 --> 00:13:34,460
‫because nowhere in our code we specified

239
00:13:34,460 --> 00:13:38,180
‫that we wanted to update the user document itself, right?

240
00:13:38,180 --> 00:13:40,603
‫And so let's fix that in the next video.

