1
00:00:02,050 --> 00:00:04,440
Now you can dive deeper into multer

2
00:00:04,440 --> 00:00:06,170
and what you can do with it.

3
00:00:06,170 --> 00:00:10,040
Accept multiple files, filter uploaded files.

4
00:00:10,040 --> 00:00:12,230
You can do a lot with multer

5
00:00:12,230 --> 00:00:13,490
and you can always dive into

6
00:00:13,490 --> 00:00:15,730
the official documentation.

7
00:00:15,730 --> 00:00:20,730
The official explanation here on the multer package page.

8
00:00:20,830 --> 00:00:23,170
If you want to learn all about it.

9
00:00:23,170 --> 00:00:25,190
There definitely is more you can do with it,

10
00:00:25,190 --> 00:00:28,140
but that's the case for all third party packages

11
00:00:28,140 --> 00:00:30,330
we're using in this course.

12
00:00:30,330 --> 00:00:32,246
Instead of digging deeper into this here,

13
00:00:32,246 --> 00:00:35,970
I want to come back to the front end here.

14
00:00:35,970 --> 00:00:37,580
When we add a new user,

15
00:00:37,580 --> 00:00:39,766
it would be great if we had a preview

16
00:00:39,766 --> 00:00:42,240
of the chosen file here,

17
00:00:42,240 --> 00:00:45,470
instead of just having the file name here.

18
00:00:45,470 --> 00:00:48,200
And it turns out that we can build such a preview,

19
00:00:48,200 --> 00:00:52,060
but there's no built in functionality for this.

20
00:00:52,060 --> 00:00:56,040
Instead, we have to build it ourselves with JavaScript.

21
00:00:56,040 --> 00:00:57,130
Now, however,

22
00:00:57,130 --> 00:00:59,790
with client site JavaScript.

23
00:00:59,790 --> 00:01:02,390
So JavaScript running in the browser,

24
00:01:02,390 --> 00:01:03,730
because keep in mind,

25
00:01:03,730 --> 00:01:06,650
JavaScript in the browser allows us to

26
00:01:06,650 --> 00:01:08,646
execute logic behind the scenes

27
00:01:08,646 --> 00:01:11,945
that may manipulate what the user sees without

28
00:01:11,945 --> 00:01:14,740
loading a new page.

29
00:01:14,740 --> 00:01:17,480
And that's exactly what we need here.

30
00:01:17,480 --> 00:01:21,350
We basically want to listen to this file picker.

31
00:01:21,350 --> 00:01:23,260
So we want to listen to events there.

32
00:01:23,260 --> 00:01:25,820
And whenever a new file is picked,

33
00:01:25,820 --> 00:01:29,030
we want to update a little preview here.

34
00:01:29,030 --> 00:01:30,060
That's my goal.

35
00:01:30,060 --> 00:01:31,560
That's what I want to do here.

36
00:01:32,650 --> 00:01:36,150
So there would be various ways of implementing this.

37
00:01:36,150 --> 00:01:38,440
I will simply go to the public folder

38
00:01:38,440 --> 00:01:41,660
and add a new scripts folder here

39
00:01:41,660 --> 00:01:45,013
with the file upload JS file.

40
00:01:46,160 --> 00:01:48,670
Or actually maybe file preview

41
00:01:48,670 --> 00:01:51,570
to make it clear that this is not there to handle

42
00:01:51,570 --> 00:01:53,600
or start file uploads,

43
00:01:53,600 --> 00:01:56,723
but only there to show a preview.

44
00:01:57,560 --> 00:02:01,060
Now for this file to have an effect in new user EJS

45
00:02:01,060 --> 00:02:03,510
we want to load this script file.

46
00:02:03,510 --> 00:02:05,600
So here in the head section,

47
00:02:05,600 --> 00:02:08,039
I'll add a script tag

48
00:02:08,039 --> 00:02:12,120
and point at slash scripts slash file

49
00:02:12,120 --> 00:02:14,340
dash preview JS

50
00:02:14,340 --> 00:02:16,660
So that file we just added.

51
00:02:16,660 --> 00:02:20,170
And add the defer attribute to load and execute it

52
00:02:20,170 --> 00:02:23,790
only once the rest of the page was parsed.

53
00:02:23,790 --> 00:02:26,388
And then don't forget this closing script tag.

54
00:02:26,388 --> 00:02:28,023
It is required.

55
00:02:29,980 --> 00:02:32,500
So now we can go back to file preview JS

56
00:02:32,500 --> 00:02:34,173
and work on our logic here.

57
00:02:35,370 --> 00:02:37,350
And in the end what I want to do here

58
00:02:37,350 --> 00:02:41,760
is I want to add a listener to this file input here.

59
00:02:41,760 --> 00:02:43,620
Thankfully it has an ID.

60
00:02:43,620 --> 00:02:47,200
So selecting it should be quite straightforward.

61
00:02:47,200 --> 00:02:50,700
And then whenever the picked file changes,

62
00:02:50,700 --> 00:02:52,653
I want to output a preview.

63
00:02:53,790 --> 00:02:57,160
So here we could add an image element

64
00:02:57,160 --> 00:03:02,160
where we say your picked image as alt text.

65
00:03:02,340 --> 00:03:05,605
And we might want to give it an ID of

66
00:03:05,605 --> 00:03:08,090
image dash preview

67
00:03:08,090 --> 00:03:10,090
so that we can get easy access

68
00:03:10,090 --> 00:03:13,280
to this element in our JavaScript code,

69
00:03:13,280 --> 00:03:15,582
because I want to set this source here

70
00:03:15,582 --> 00:03:18,383
dynamically with JavaScript.

71
00:03:20,520 --> 00:03:22,710
For this back and file preview,

72
00:03:22,710 --> 00:03:25,640
let's get access to the file picker

73
00:03:25,640 --> 00:03:30,290
element by using document get element by ID

74
00:03:31,580 --> 00:03:35,223
and then image was the ID of that input element.

75
00:03:36,480 --> 00:03:41,480
So I am referring to this input element with the ID image.

76
00:03:41,520 --> 00:03:43,183
So to the button here in the end,

77
00:03:44,210 --> 00:03:45,940
and I also want to get access to the

78
00:03:45,940 --> 00:03:48,660
image preview image element here.

79
00:03:48,660 --> 00:03:51,520
So we can also get the image preview

80
00:03:53,610 --> 00:03:57,610
element here by using document get element by ID

81
00:03:57,610 --> 00:03:59,500
and then this ID.

82
00:03:59,500 --> 00:04:00,393
Like that.

83
00:04:02,650 --> 00:04:05,640
Now for the file picker element,

84
00:04:05,640 --> 00:04:07,373
we can add an event listener.

85
00:04:08,290 --> 00:04:10,900
It's not a click I want to listen to though.

86
00:04:10,900 --> 00:04:14,130
I want to listen to the change event.

87
00:04:14,130 --> 00:04:17,370
That's an event that will be emitted whenever the veil

88
00:04:17,370 --> 00:04:20,423
you picked in this input will change.

89
00:04:21,790 --> 00:04:23,740
It's a built in event we can listen to.

90
00:04:24,720 --> 00:04:28,970
And then I'll define a function, show preview,

91
00:04:28,970 --> 00:04:31,100
could be the function name.

92
00:04:31,100 --> 00:04:34,696
And I will set this as a second parameter value here

93
00:04:34,696 --> 00:04:37,000
without parentheses though,

94
00:04:37,000 --> 00:04:39,510
so that it's not executed immediately,

95
00:04:39,510 --> 00:04:42,900
but instead only when that change event occurs.

96
00:04:42,900 --> 00:04:45,520
That's in the end what we already did dozens of times

97
00:04:45,520 --> 00:04:47,646
in this course before when we also worked

98
00:04:47,646 --> 00:04:51,860
with event listeners in our browser site JavaScript code.

99
00:04:51,860 --> 00:04:54,943
We're doing it again here just for the change event now.

100
00:04:56,380 --> 00:04:58,140
So now it's in show preview

101
00:04:58,140 --> 00:05:01,700
where I want to check if a file was picked,

102
00:05:01,700 --> 00:05:06,440
because change firing does not mean that a file was picked.

103
00:05:06,440 --> 00:05:08,850
We might have a file picked before

104
00:05:08,850 --> 00:05:11,000
and now we unselected it.

105
00:05:11,000 --> 00:05:13,820
So we want to check if a file is picked now,

106
00:05:13,820 --> 00:05:15,330
and if it is picked,

107
00:05:15,330 --> 00:05:17,973
then we actually want to show a preview.

108
00:05:19,010 --> 00:05:21,360
For this here in show preview,

109
00:05:21,360 --> 00:05:23,720
we can use the file picker element.

110
00:05:23,720 --> 00:05:27,480
So it is input element which is our file picker.

111
00:05:27,480 --> 00:05:31,090
And there we'll have a files

112
00:05:31,090 --> 00:05:32,720
property.

113
00:05:32,720 --> 00:05:33,760
And that's important.

114
00:05:33,760 --> 00:05:36,900
It's files not file.

115
00:05:36,900 --> 00:05:38,883
It's plural instead,

116
00:05:39,780 --> 00:05:43,150
because theoretically you can also use a file picker

117
00:05:43,150 --> 00:05:44,993
to select multiple files.

118
00:05:46,050 --> 00:05:49,360
So here I got my files and I first of all

119
00:05:49,360 --> 00:05:52,820
want to check if files is maybe false.

120
00:05:52,820 --> 00:05:55,850
If it is it means we don't have any files.

121
00:05:55,850 --> 00:05:57,880
And in this case I want to just return

122
00:05:57,880 --> 00:06:00,023
and not execute any other code.

123
00:06:01,030 --> 00:06:03,430
I also want to check if it's maybe not false,

124
00:06:03,430 --> 00:06:05,860
but files length is zero,

125
00:06:05,860 --> 00:06:08,474
which also means we have no files.

126
00:06:08,474 --> 00:06:10,593
In that case I just return here.

127
00:06:11,840 --> 00:06:14,250
If we make it past this check we know that we have

128
00:06:14,250 --> 00:06:15,830
at least one file.

129
00:06:15,830 --> 00:06:18,600
In our case here, exactly one file.

130
00:06:18,600 --> 00:06:23,260
So then the picked file is files zero.

131
00:06:23,260 --> 00:06:25,831
So the first, and in our case, only file

132
00:06:25,831 --> 00:06:28,470
that could have been picked here.

133
00:06:28,470 --> 00:06:31,053
That's now the file we want to preview.

134
00:06:31,053 --> 00:06:34,300
And therefore here, I then want to set

135
00:06:35,460 --> 00:06:38,260
image preview element, so this image element,

136
00:06:38,260 --> 00:06:41,110
which we prepared for previewing the file,

137
00:06:41,110 --> 00:06:43,230
dot SRC

138
00:06:43,230 --> 00:06:45,069
equal to

139
00:06:45,069 --> 00:06:48,800
URL, which is a built in object,

140
00:06:48,800 --> 00:06:52,593
a built in class in the end that exists in JavaScript,

141
00:06:53,550 --> 00:06:54,970
dot

142
00:06:54,970 --> 00:06:57,360
create object URL,

143
00:06:57,360 --> 00:07:00,640
which is a utility method built in here.

144
00:07:00,640 --> 00:07:02,620
So it's built into the browser,

145
00:07:02,620 --> 00:07:07,520
that will take a file and convert a URL that can be used

146
00:07:07,520 --> 00:07:08,973
as an image source.

147
00:07:10,460 --> 00:07:15,460
So, and here we pass picked file to create object URL.

148
00:07:15,900 --> 00:07:20,230
So that will generate a link, a URL to that file

149
00:07:20,230 --> 00:07:21,750
the user picked.

150
00:07:21,750 --> 00:07:24,280
And it is important to understand that,

151
00:07:24,280 --> 00:07:28,940
at this point the file has not been uploaded yet.

152
00:07:28,940 --> 00:07:33,670
So we are not generating a URL to that file on our server

153
00:07:33,670 --> 00:07:35,300
or anything like that.

154
00:07:35,300 --> 00:07:38,820
The file is still on the computer of the user

155
00:07:38,820 --> 00:07:41,300
who's visiting this page.

156
00:07:41,300 --> 00:07:44,994
So this method is simply creating a local URL,

157
00:07:44,994 --> 00:07:49,040
which only works on the computer of this visitor

158
00:07:49,040 --> 00:07:53,510
to this file on the visitor's computer.

159
00:07:53,510 --> 00:07:55,260
So that's what we're doing here.

160
00:07:55,260 --> 00:07:58,200
And then we're using this local URL

161
00:07:58,200 --> 00:08:01,423
as a source for our preview image element.

162
00:08:03,220 --> 00:08:05,960
I also want to make sure that if we don't have any files

163
00:08:05,960 --> 00:08:07,540
before I return,

164
00:08:07,540 --> 00:08:11,240
I set image, preview element dot style dot display,

165
00:08:11,240 --> 00:08:13,263
to, none, to hide it.

166
00:08:14,540 --> 00:08:15,940
And on the other hand,

167
00:08:15,940 --> 00:08:18,890
I set it to, block, to show it,

168
00:08:18,890 --> 00:08:22,230
once we do have an image to preview.

169
00:08:24,510 --> 00:08:26,370
And then with this code added here

170
00:08:26,370 --> 00:08:29,060
with these couple of lines of code here added,

171
00:08:29,060 --> 00:08:31,500
we can now save everything again,

172
00:08:31,500 --> 00:08:33,740
reload this page.

173
00:08:33,740 --> 00:08:35,350
And here, I want to make sure that

174
00:08:35,350 --> 00:08:38,140
this is not visible here.

175
00:08:38,140 --> 00:08:41,870
This, alt text, right from the start.

176
00:08:41,870 --> 00:08:46,130
And for this I want to hide this image preview as a default.

177
00:08:46,130 --> 00:08:51,130
So therefore we can go to the profiles CSS file

178
00:08:51,300 --> 00:08:55,170
and select this image preview element

179
00:08:55,170 --> 00:08:56,920
by its ID

180
00:08:56,920 --> 00:08:59,673
and set display to none as a default.

181
00:09:00,820 --> 00:09:04,050
So that by default, this image preview image element

182
00:09:04,050 --> 00:09:05,223
is not shown.

183
00:09:06,760 --> 00:09:09,890
And now if we reload here it's not visible.

184
00:09:09,890 --> 00:09:11,533
And if I pick a file,

185
00:09:12,450 --> 00:09:13,440
like this,

186
00:09:13,440 --> 00:09:14,930
here's my preview.

187
00:09:14,930 --> 00:09:17,480
Maybe we can improve the styling,

188
00:09:17,480 --> 00:09:19,330
but it's there.

189
00:09:19,330 --> 00:09:21,850
If I opened a picker again and cancel,

190
00:09:21,850 --> 00:09:24,343
I unselect the file and it's gone again.

191
00:09:25,910 --> 00:09:28,600
Now to optimize the way this is displayed,

192
00:09:28,600 --> 00:09:30,520
I'll go back to image preview,

193
00:09:30,520 --> 00:09:32,690
and I'll give it a width of let's say,

194
00:09:32,690 --> 00:09:35,830
five REM and a height of five REM,

195
00:09:35,830 --> 00:09:38,450
or maybe even just two dot five REM,

196
00:09:38,450 --> 00:09:40,383
so that we have a small preview.

197
00:09:42,530 --> 00:09:45,740
And I'll also set object fit to cover

198
00:09:45,740 --> 00:09:48,760
so that we don't have any distortion in the image,

199
00:09:48,760 --> 00:09:53,200
since object fit will ensure that the aspect ratio

200
00:09:53,200 --> 00:09:57,570
is not destroyed, and instead the image is simply clipped

201
00:09:57,570 --> 00:09:59,623
to fit into these boundaries.

202
00:10:02,310 --> 00:10:05,400
So with that back here, if we reload,

203
00:10:05,400 --> 00:10:06,750
if I now choose an image,

204
00:10:06,750 --> 00:10:09,658
we got this smaller preview and now we can still

205
00:10:09,658 --> 00:10:11,513
submit and upload it.

206
00:10:12,710 --> 00:10:14,230
Of course you can fine tune this.

207
00:10:14,230 --> 00:10:15,860
You can improve the styling,

208
00:10:15,860 --> 00:10:18,320
but that's how you could add an image preview.

209
00:10:18,320 --> 00:10:21,833
And that's overall how you can handle file uploads.

