1
00:00:00,050 --> 00:00:00,520
Okay.

2
00:00:00,530 --> 00:00:04,939
And up next, let's refactor our upload image functionality.

3
00:00:05,090 --> 00:00:12,950
You see, since I recorded the course, Render has made some changes and we can only implement such

4
00:00:12,980 --> 00:00:16,610
uploads approach if we use a paid option.

5
00:00:16,610 --> 00:00:22,550
So we need to use a disk space on render and it's not available with free option.

6
00:00:22,550 --> 00:00:28,350
So don't be surprised if upload image functionality does not work on render.

7
00:00:28,370 --> 00:00:34,610
Now, in order to fix it, we'll need to install one more package and we'll need to make changes to

8
00:00:34,610 --> 00:00:35,970
our existing code.

9
00:00:35,990 --> 00:00:38,810
So for starters, I want to remove the public.

10
00:00:38,810 --> 00:00:41,840
So effectively we're not using it for our front end.

11
00:00:41,840 --> 00:00:45,110
And after this video, we're also not going to use it.

12
00:00:46,020 --> 00:00:48,810
With our upload image functionality.

13
00:00:48,810 --> 00:00:50,880
So let's start from the scratch.

14
00:00:50,880 --> 00:00:56,340
We want to remove the public folder altogether and if everything is correct, if you take a look at

15
00:00:56,340 --> 00:01:01,890
the server, notice we're not pointing to a public here anymore anyway.

16
00:01:02,160 --> 00:01:10,140
Now as far as the changes you see, instead of using a disk space with Multer, we will actually use

17
00:01:10,140 --> 00:01:11,460
a memory storage.

18
00:01:11,460 --> 00:01:18,300
So remember when we set up our middleware, the malter one, we used disk storage.

19
00:01:18,300 --> 00:01:21,330
So effectively we store it on a disk.

20
00:01:21,420 --> 00:01:25,800
Notice we even have this path over here public forward slash uploads.

21
00:01:25,890 --> 00:01:29,460
Now there's another option, a memory storage.

22
00:01:29,520 --> 00:01:33,120
So essentially we'll save our image as a buffer.

23
00:01:33,120 --> 00:01:41,730
Now the problem is we cannot directly push buffer to a Cloudinary so we still want to store our image

24
00:01:41,730 --> 00:01:49,630
in a cloudinary However, we will need some extra package that will take this buffer and turn it into

25
00:01:49,630 --> 00:01:52,170
something that Cloudinary can work with.

26
00:01:52,180 --> 00:01:55,540
So long story short, here's what we want to do.

27
00:01:55,750 --> 00:01:57,340
We want to install this package.

28
00:01:57,340 --> 00:02:01,900
And again, it depends when you start watching the course.

29
00:02:02,640 --> 00:02:06,150
Of course I'll add it to the packages in the Readme.

30
00:02:06,480 --> 00:02:10,130
So if you're watching this later, most likely you already have this package.

31
00:02:10,139 --> 00:02:15,870
If not, then of course you'll need to install now in order to check it, just go to package Json and

32
00:02:15,870 --> 00:02:18,150
again, if you see it here, then you're good.

33
00:02:18,150 --> 00:02:20,310
If not, then you'll need to install.

34
00:02:20,400 --> 00:02:27,210
So let me navigate back to my terminal and I just want to go with this command.

35
00:02:27,960 --> 00:02:29,120
So let me run it.

36
00:02:29,130 --> 00:02:36,890
I want to install this package and if everything is correct, I want to go with NPM and then run Dev.

37
00:02:36,900 --> 00:02:39,860
So again, we're going to work on our project locally.

38
00:02:39,870 --> 00:02:45,090
Once everything is done, we'll push it up to a GitHub and then from there Render is going to pick it

39
00:02:45,090 --> 00:02:47,480
up and build our project.

40
00:02:47,490 --> 00:02:49,170
So I installed the package.

41
00:02:49,170 --> 00:02:55,020
Okay, now we want to go to a Multer middleware and like I said, make some changes.

42
00:02:55,020 --> 00:02:56,820
So for starters over here.

43
00:02:57,790 --> 00:03:05,500
Instead of disk storage, we're going to go with Malter and Dot and the other one is memory storage.

44
00:03:05,530 --> 00:03:08,670
Now here we are now going to provide any arguments.

45
00:03:08,680 --> 00:03:14,380
Essentially we'll have our storage that is equal to a memory storage and then we still have this upload,

46
00:03:14,380 --> 00:03:15,970
which we're exporting.

47
00:03:15,970 --> 00:03:20,290
And then if you remember in the roots in the user root.

48
00:03:20,920 --> 00:03:25,000
We went with upload single and we're still looking for Avatar.

49
00:03:25,000 --> 00:03:28,360
So this part does not change.

50
00:03:28,360 --> 00:03:30,520
But here's what we want to do.

51
00:03:30,550 --> 00:03:34,480
We want to go back to this middleware once we have installed.

52
00:03:35,300 --> 00:03:38,180
Essentially our package we want to import.

53
00:03:38,180 --> 00:03:39,200
And this is important.

54
00:03:39,230 --> 00:03:41,600
We want to go here with data.

55
00:03:41,600 --> 00:03:44,600
And as far as my name, I'm going to go with parser.

56
00:03:44,690 --> 00:03:49,940
But where we're importing from this is going to be very specific.

57
00:03:49,940 --> 00:03:56,360
So we want to go with our package then forward slash and then we're looking for parser, but make sure

58
00:03:56,360 --> 00:03:59,920
you add JS, otherwise you'll have a bug.

59
00:03:59,930 --> 00:04:06,020
And also I want to grab a path module which of course is built in.

60
00:04:06,690 --> 00:04:12,810
To a node and therefore I'm just going to go with import path from path.

61
00:04:13,110 --> 00:04:14,910
So let's save this one.

62
00:04:15,240 --> 00:04:20,740
And essentially there's going to be a helper function which will also export.

63
00:04:20,760 --> 00:04:24,210
So let's start over here by creating that function.

64
00:04:24,210 --> 00:04:31,020
So notice I'll have this default upload since I don't want to change my code in too many places in the

65
00:04:31,020 --> 00:04:31,650
application.

66
00:04:31,650 --> 00:04:33,830
So therefore I'm keeping this the same.

67
00:04:33,840 --> 00:04:39,570
And remember, you can only have one export default per file and therefore obviously this is going to

68
00:04:39,570 --> 00:04:41,250
be named export.

69
00:04:41,250 --> 00:04:43,800
And in my case, I'm going to call this format.

70
00:04:44,650 --> 00:04:45,610
An image.

71
00:04:45,610 --> 00:04:51,420
Now, this format, image function is going to be looking for one thing and one thing only.

72
00:04:51,430 --> 00:04:58,720
If you remember, when we run Malter, essentially we add this file to a request object.

73
00:04:58,720 --> 00:05:03,430
Remember it was located in rec dot file and don't worry, we will log it of course, together.

74
00:05:03,430 --> 00:05:06,280
So here for now, let's just log.

75
00:05:07,310 --> 00:05:13,580
The file to see whether everything worked correctly and then we'll add the functionality.

76
00:05:13,610 --> 00:05:19,470
So now let's navigate to the user controller and we're looking for our update user.

77
00:05:19,490 --> 00:05:27,470
So we're not going to use this await link anymore because again, we're not using disk storage, so

78
00:05:27,470 --> 00:05:31,760
please make sure you also follow the same setup.

79
00:05:32,580 --> 00:05:38,130
We want to remove this line of code and pretty much everything else is going to stay the same.

80
00:05:38,920 --> 00:05:42,070
So we only want to make this change.

81
00:05:42,070 --> 00:05:43,330
And then, of course.

82
00:05:43,900 --> 00:05:45,760
We'll implement our package.

83
00:05:45,920 --> 00:05:48,670
Now, also, we don't need this anymore.

84
00:05:48,880 --> 00:05:50,510
So we can remove this one.

85
00:05:50,530 --> 00:05:57,010
However, we do want to import format an image from our middleware.

86
00:05:57,040 --> 00:06:02,770
Then let's keep on moving and notice where I have here the rec dot file.

87
00:06:03,340 --> 00:06:10,090
Effectively, I want to format the image and once I get back the response, that's the one that I'm

88
00:06:10,090 --> 00:06:12,430
going to upload to a cloudinary.

89
00:06:12,790 --> 00:06:13,330
And you know what?

90
00:06:13,330 --> 00:06:15,550
For now I'm just going to return.

91
00:06:15,580 --> 00:06:21,970
So this is just going to be temporary and above the return I'm going to set up const file is equal to

92
00:06:22,000 --> 00:06:23,290
format image.

93
00:06:23,290 --> 00:06:27,220
And now like I said, we want to pass in that file in there.

94
00:06:27,220 --> 00:06:29,370
And of course at the moment we're just logging.

95
00:06:29,380 --> 00:06:32,260
So now let's just navigate back to the browser.

96
00:06:32,290 --> 00:06:35,940
Now I have quite a few tabs open over here, so you know what?

97
00:06:35,950 --> 00:06:36,790
Let me close it.

98
00:06:36,790 --> 00:06:41,920
So this is going to be my render one, which of course I want to showcase at the end of the video.

99
00:06:41,920 --> 00:06:44,720
So for now, let's just go to file 173.

100
00:06:44,750 --> 00:06:50,570
Now, in this case, I do want to log in as my user because otherwise with a temp one, I'm not going

101
00:06:50,570 --> 00:06:52,970
to be able to showcase that.

102
00:06:54,060 --> 00:06:56,840
Well, then let me provide over here the password.

103
00:06:57,760 --> 00:06:58,860
Let me log in.

104
00:06:58,870 --> 00:07:01,390
Profile over here again for now.

105
00:07:01,600 --> 00:07:03,550
Of course, nothing is going to work.

106
00:07:03,580 --> 00:07:06,520
I simply want to showcase what are we getting?

107
00:07:06,520 --> 00:07:08,470
So let me click on Submit.

108
00:07:09,520 --> 00:07:10,090
Okay.

109
00:07:10,090 --> 00:07:13,630
It says here submitting since, of course, we're just returning over here.

110
00:07:13,630 --> 00:07:15,640
I'm not sending a response.

111
00:07:15,700 --> 00:07:17,850
What I'm interested, of course, is this.

112
00:07:17,860 --> 00:07:21,460
So this is what we're logging in our format image.

113
00:07:21,460 --> 00:07:22,140
Correct.

114
00:07:22,150 --> 00:07:23,710
Again, same deal.

115
00:07:23,740 --> 00:07:26,980
We still have the rec file object.

116
00:07:26,980 --> 00:07:31,450
The difference, of course, is that we're not saving this on a disk anywhere.

117
00:07:31,450 --> 00:07:32,740
So this one is in memory.

118
00:07:32,740 --> 00:07:35,160
And like I said, notice this buffer.

119
00:07:35,170 --> 00:07:36,700
So that's the difference.

120
00:07:36,700 --> 00:07:44,770
So now we want to use our package and essentially format to something cloudinary can work with, because

121
00:07:44,770 --> 00:07:51,250
if you'll try to pass this buffer directly like we did previously with rec dot file and whatever was

122
00:07:51,250 --> 00:07:53,920
the property, it's not going to work.

123
00:07:53,950 --> 00:08:00,220
So now let's navigate back to Multer middleware and the first thing we want to do in this file is to

124
00:08:00,220 --> 00:08:04,960
invoke new and then whatever you use the name over here.

125
00:08:05,020 --> 00:08:14,350
So I'm going to go with const, then parser and set it equal to new data and parser and we want to invoke

126
00:08:14,350 --> 00:08:14,620
it.

127
00:08:14,620 --> 00:08:16,030
So that's the first step.

128
00:08:16,030 --> 00:08:18,670
And once I save I get the error in the console.

129
00:08:18,670 --> 00:08:24,300
Don't worry, it's because we're not setting up the return in the update user.

130
00:08:24,310 --> 00:08:25,570
We'll fix that in a second.

131
00:08:25,570 --> 00:08:32,260
So we're going to go here with new data parser and then in the format image instead of the log.

132
00:08:32,260 --> 00:08:35,409
First I want to grab the extension.

133
00:08:35,409 --> 00:08:38,590
So essentially the package is looking for the extension.

134
00:08:38,590 --> 00:08:42,280
So we're going to go over here with const, then file extension.

135
00:08:43,169 --> 00:08:46,340
That's going to be the name of my variable.

136
00:08:46,340 --> 00:08:50,120
And in order to get it, I'm going to use the path module.

137
00:08:50,120 --> 00:08:54,290
So it has this extension name property.

138
00:08:54,290 --> 00:08:57,800
And in here we simply want to go with file.

139
00:08:57,800 --> 00:09:00,800
Remember, it has this original name.

140
00:09:00,800 --> 00:09:01,940
Let's scroll up.

141
00:09:02,150 --> 00:09:03,890
Notice over here this original name.

142
00:09:03,890 --> 00:09:05,510
That's what we want to use.

143
00:09:05,750 --> 00:09:09,110
Therefore I'm going to go dot and then original name.

144
00:09:10,580 --> 00:09:13,610
And then we want to turn this into a string.

145
00:09:13,730 --> 00:09:21,860
So we're going to go to string, we invoke that, and then what we want to return from this format,

146
00:09:21,860 --> 00:09:24,990
image function, we want to go with our parser.

147
00:09:25,010 --> 00:09:28,070
So essentially what we're getting back, that's our instance.

148
00:09:28,100 --> 00:09:30,710
Then the method name is format.

149
00:09:30,740 --> 00:09:33,860
We want to pass in the file extension.

150
00:09:33,860 --> 00:09:38,780
And then the second argument is going to be file dot and then the buffer.

151
00:09:39,050 --> 00:09:42,260
So again, this is coming from here.

152
00:09:42,620 --> 00:09:48,410
And lastly, we want to go with dot content and that's the one we're going to pass into a Cloudinary.

153
00:09:48,620 --> 00:09:53,130
So now let's navigate back to our user controller.

154
00:09:53,150 --> 00:09:55,430
Let's start by removing the return.

155
00:09:56,140 --> 00:10:01,900
And instead of this req dot file dot path, we simply want to pass here the file.

156
00:10:02,770 --> 00:10:04,270
So set it up over here.

157
00:10:04,270 --> 00:10:06,990
And like I said, everything else stays the same.

158
00:10:07,000 --> 00:10:15,160
Yes, we still want to remove the old picture if the user is adding a new one.

159
00:10:15,160 --> 00:10:22,600
And yes, we still want to grab the secure URL, the public ID and all that, so nothing else changes

160
00:10:22,600 --> 00:10:24,460
in the update.

161
00:10:24,460 --> 00:10:25,450
User one.

162
00:10:26,030 --> 00:10:28,850
We only change the format.

163
00:10:28,850 --> 00:10:35,570
So instead of saving it on a disk, now we're saving it in a memory and then we're formatting this buffer

164
00:10:35,570 --> 00:10:38,630
into something cloudinary can work with.

165
00:10:38,840 --> 00:10:44,330
And before we test it locally, I actually want to push this up since of course I want to showcase that

166
00:10:44,330 --> 00:10:46,570
everything works on render.

167
00:10:46,580 --> 00:10:54,320
So let's say over here fix update User Okay, let's push this up.

168
00:10:54,470 --> 00:10:59,060
And for starters, let's just take a look what's happening here locally.

169
00:10:59,060 --> 00:11:01,880
So this is going to be my 5173.

170
00:11:02,120 --> 00:11:02,510
Okay.

171
00:11:02,510 --> 00:11:05,480
Again, I'll have to log in then.

172
00:11:05,480 --> 00:11:07,550
Let me navigate to a profile.

173
00:11:07,610 --> 00:11:09,290
And I'm using this image over here.

174
00:11:09,290 --> 00:11:11,210
So let me switch to another one.

175
00:11:12,550 --> 00:11:15,490
Let me change the name.

176
00:11:15,490 --> 00:11:16,120
Maybe.

177
00:11:17,100 --> 00:11:18,480
Well, let's go.

178
00:11:19,370 --> 00:11:19,940
Yep.

179
00:11:20,090 --> 00:11:22,730
Notice I nicely changed the image.

180
00:11:22,730 --> 00:11:25,250
And also, of course, name is different right now.

181
00:11:25,250 --> 00:11:27,590
So now let's navigate to a render.

182
00:11:27,590 --> 00:11:29,630
Let's see what's happening over here.

183
00:11:29,870 --> 00:11:37,880
It looks like Render is still building my application, so I'm going to wait and I'll test it when everything

184
00:11:37,880 --> 00:11:38,960
is ready to go.

185
00:11:38,960 --> 00:11:44,030
And once render is done building my project, let me navigate to URL.

186
00:11:44,480 --> 00:11:45,890
I'll close this one.

187
00:11:45,890 --> 00:11:47,120
So that's my local one.

188
00:11:47,120 --> 00:11:47,660
Okay.

189
00:11:47,900 --> 00:11:50,270
And then again I'll have to log in.

190
00:11:50,630 --> 00:11:52,220
So that doesn't change.

191
00:11:52,220 --> 00:11:57,170
And yes, we still want to do it with some kind of user that actually can.

192
00:11:57,990 --> 00:12:01,890
Update the profile since the demo one is not allowed.

193
00:12:02,280 --> 00:12:04,050
Then let's navigate to profile.

194
00:12:04,080 --> 00:12:06,530
Notice this is going to be my current image.

195
00:12:06,540 --> 00:12:08,190
So now let me go.

196
00:12:09,380 --> 00:12:10,700
And look for another one.

197
00:12:11,270 --> 00:12:13,880
And here I'm going to go back to John.

198
00:12:14,180 --> 00:12:21,740
And again, if everything is correct now, we'll be able to update the image on render platform even

199
00:12:21,740 --> 00:12:23,570
with the free option.

