WEBVTT

1
00:00:01.110 --> 00:00:04.010
<v ->Hello, and welcome to the biggest</v>

2
00:00:04.010 --> 00:00:07.420
and most complete project of the course.

3
00:00:07.420 --> 00:00:10.850
And this is kind of the final project of this course,

4
00:00:10.850 --> 00:00:13.280
which brings everything that we have learnt,

5
00:00:13.280 --> 00:00:14.580
up until this point,

6
00:00:14.580 --> 00:00:17.700
into one big and beautiful project.

7
00:00:17.700 --> 00:00:20.610
And so, just like with the Mapty project before,

8
00:00:20.610 --> 00:00:22.000
Let's actually start,

9
00:00:22.000 --> 00:00:24.493
by taking a look, at this project.

10
00:00:26.040 --> 00:00:27.980
And, this is it.

11
00:00:27.980 --> 00:00:30.573
So this is the Forkify application,

12
00:00:30.573 --> 00:00:32.510
that we will build together

13
00:00:32.510 --> 00:00:35.090
over the next couple of hours.

14
00:00:35.090 --> 00:00:38.620
So this application is all about searching for recipes

15
00:00:38.620 --> 00:00:40.003
and displaying them,

16
00:00:40.937 --> 00:00:42.290
here in our user interface.

17
00:00:42.290 --> 00:00:44.490
And in order to get a good idea,

18
00:00:44.490 --> 00:00:46.870
of how this application actually works,

19
00:00:46.870 --> 00:00:50.220
you should probably follow along, this demonstration,

20
00:00:50.220 --> 00:00:53.537
by going to this URL, soforkifyv2.netlify.app.

21
00:00:57.340 --> 00:01:00.663
And so let's search for pizza here.

22
00:01:02.100 --> 00:01:03.910
And so you see, that right away,

23
00:01:03.910 --> 00:01:06.280
here on this left sidebar,

24
00:01:06.280 --> 00:01:08.320
we get all of these results.

25
00:01:08.320 --> 00:01:10.530
And when we have more than ten results,

26
00:01:10.530 --> 00:01:14.700
they actually, get divided up on multiple pages.

27
00:01:14.700 --> 00:01:17.180
So we have this nice pagination here,

28
00:01:17.180 --> 00:01:22.180
which is a very common feature of web applications. Right?

29
00:01:23.690 --> 00:01:26.350
So you've seen this all the time probably.

30
00:01:26.350 --> 00:01:27.940
And so now in this project,

31
00:01:27.940 --> 00:01:31.130
you will learn how to implement this yourself.

32
00:01:31.130 --> 00:01:33.930
Now, okay. And now let's actually click

33
00:01:33.930 --> 00:01:36.230
on one of these recipes,

34
00:01:36.230 --> 00:01:37.960
and you see that then it shows up,

35
00:01:37.960 --> 00:01:39.890
here on the right side.

36
00:01:39.890 --> 00:01:41.310
So we have the cooking time,

37
00:01:41.310 --> 00:01:44.150
the servings, all the ingredients,

38
00:01:44.150 --> 00:01:46.040
and then also a link to the page,

39
00:01:46.040 --> 00:01:48.053
where the recipe actually comes from.

40
00:01:49.440 --> 00:01:50.930
Now here in the servings,

41
00:01:50.930 --> 00:01:52.670
we can actually decrease,

42
00:01:52.670 --> 00:01:56.220
or also increase the number of servings

43
00:01:56.220 --> 00:01:58.660
and as you see down here, the ingredients,

44
00:01:58.660 --> 00:02:01.483
will then automatically get updated.

45
00:02:02.600 --> 00:02:05.860
Right? Then another cool thing that we can do,

46
00:02:05.860 --> 00:02:08.550
is to bookmark recipes.

47
00:02:08.550 --> 00:02:10.130
So as we click here,

48
00:02:10.130 --> 00:02:12.980
then that button changes,

49
00:02:12.980 --> 00:02:15.680
and we also got that recipe bookmark,

50
00:02:15.680 --> 00:02:18.140
here in this nice panel now.

51
00:02:18.140 --> 00:02:21.870
And here you see, I already had a bookmark before,

52
00:02:21.870 --> 00:02:23.490
and as we click that,

53
00:02:23.490 --> 00:02:26.143
it will then of course move to that one.

54
00:02:27.950 --> 00:02:29.690
Now, if we click here again,

55
00:02:29.690 --> 00:02:33.300
then that will basically unbookmark the recipe,

56
00:02:33.300 --> 00:02:35.063
and so you see that now it's gone,

57
00:02:36.690 --> 00:02:38.930
and let's do the same here

58
00:02:38.930 --> 00:02:40.450
and so now it's empty

59
00:02:40.450 --> 00:02:43.833
and we get this kind of warning message instead.

60
00:02:46.240 --> 00:02:50.763
Now right? Now finally, we can actually also add recipes.

61
00:02:51.770 --> 00:02:53.873
So, just click on this button,

62
00:02:54.870 --> 00:02:58.620
and then here, we can just fill in this form.

63
00:02:58.620 --> 00:02:59.890
Now in this demo version,

64
00:02:59.890 --> 00:03:01.940
that's actually not going to work,

65
00:03:01.940 --> 00:03:04.780
because that would very quickly clutter,

66
00:03:04.780 --> 00:03:06.293
this entire application here.

67
00:03:07.500 --> 00:03:10.600
Now, what's special about this recipe upload,

68
00:03:10.600 --> 00:03:13.740
is that, all the recipes that you upload yourself,

69
00:03:13.740 --> 00:03:16.023
will only be visible for yourself.

70
00:03:16.920 --> 00:03:20.140
So, here for example, I have this JS PIZZA,

71
00:03:20.140 --> 00:03:22.980
which was done by me.

72
00:03:22.980 --> 00:03:25.660
And so therefore, it has this icon here,

73
00:03:25.660 --> 00:03:27.750
and also this icon here.

74
00:03:27.750 --> 00:03:30.550
So it means that it was the user itself.

75
00:03:30.550 --> 00:03:32.490
Now, when you open up this page

76
00:03:32.490 --> 00:03:36.710
and search for pizza, then this recipe here,

77
00:03:36.710 --> 00:03:39.620
should probably also appear for yourself

78
00:03:39.620 --> 00:03:40.800
but that's only because,

79
00:03:40.800 --> 00:03:45.380
this version has like a fixed developer API key.

80
00:03:45.380 --> 00:03:49.900
And so each recipe is associated to a certain developer key

81
00:03:49.900 --> 00:03:53.150
and we will see what that means, by the end of the section,

82
00:03:53.150 --> 00:03:56.710
when we actually implement this. Now right?

83
00:03:56.710 --> 00:03:58.950
But I think that's actually it.

84
00:03:58.950 --> 00:04:00.106
So that's the whole functionality,

85
00:04:00.106 --> 00:04:04.570
of the Forkify application, which seems pretty simple

86
00:04:04.570 --> 00:04:07.260
but it will actually be a lot of work,

87
00:04:07.260 --> 00:04:09.200
to implement all of this.

88
00:04:09.200 --> 00:04:10.033
And so hopefully,

89
00:04:10.033 --> 00:04:13.650
it's gonna be a great learning experience for you.

90
00:04:13.650 --> 00:04:17.070
And once again I tried to design this application,

91
00:04:17.070 --> 00:04:20.010
like as modern and beautiful as possible,

92
00:04:20.010 --> 00:04:22.390
so that you end up with a real nice application

93
00:04:22.390 --> 00:04:26.130
in you portfolio in the end. Now okay.

94
00:04:26.130 --> 00:04:27.860
But will all that being said,

95
00:04:27.860 --> 00:04:30.663
let's now actually go plan this application.

96
00:04:32.270 --> 00:04:33.680
So, now that we know,

97
00:04:33.680 --> 00:04:37.220
what the project looks like and also how it works.

98
00:04:37.220 --> 00:04:39.760
We need to go through the same planning steps,

99
00:04:39.760 --> 00:04:42.620
that we did in the Mapty project.

100
00:04:42.620 --> 00:04:44.690
Now in this case, we will actually leave,

101
00:04:44.690 --> 00:04:47.490
the architecture for a bit later

102
00:04:47.490 --> 00:04:49.870
and only talk about the user stories,

103
00:04:49.870 --> 00:04:54.360
features and also about the flow chart for now.

104
00:04:54.360 --> 00:04:57.700
And to start, remember that a user story,

105
00:04:57.700 --> 00:05:01.190
is a description, of the application's functionality

106
00:05:01.190 --> 00:05:03.810
from a user's perspective.

107
00:05:03.810 --> 00:05:06.870
So basically, when we write user stories,

108
00:05:06.870 --> 00:05:10.940
we need to put ourselves in the shoes of our users.

109
00:05:10.940 --> 00:05:13.720
Now, all the user stories, put together,

110
00:05:13.720 --> 00:05:16.060
will then provide a clear picture,

111
00:05:16.060 --> 00:05:19.250
of how the whole application is gonna work.

112
00:05:19.250 --> 00:05:21.090
And so based on these stories,

113
00:05:21.090 --> 00:05:22.820
we will then be able to implement,

114
00:05:22.820 --> 00:05:25.610
all our application's features.

115
00:05:25.610 --> 00:05:28.410
all right, so let's say that we are now,

116
00:05:28.410 --> 00:05:31.960
kind of the project manager for Forkify.

117
00:05:31.960 --> 00:05:33.570
And let's also pretend,

118
00:05:33.570 --> 00:05:37.060
that we didn't see the final version of the project yet.

119
00:05:37.060 --> 00:05:39.990
Because of course, we have to write user stories,

120
00:05:39.990 --> 00:05:44.720
usually before we implement the project. Right?

121
00:05:44.720 --> 00:05:45.760
But in this case,

122
00:05:45.760 --> 00:05:48.880
since we are kind of doing it together here in this video,

123
00:05:48.880 --> 00:05:51.380
of course it's better when we already know,

124
00:05:51.380 --> 00:05:53.200
what the application looks like.

125
00:05:53.200 --> 00:05:54.430
But in the real world,

126
00:05:54.430 --> 00:05:57.203
this is basically gonna be your starting point.

127
00:05:58.070 --> 00:06:02.267
So, for this project, the first user story could be,

128
00:06:02.267 --> 00:06:05.357
"As a user, I want to search for recipes,

129
00:06:05.357 --> 00:06:09.150
"so that I can find new ideas for meals."

130
00:06:09.150 --> 00:06:12.667
And so you see again, we are using the format of,

131
00:06:12.667 --> 00:06:16.887
"As a type of user, I want to..." And then an action,

132
00:06:16.887 --> 00:06:20.080
"so that..." and then a benefit.

133
00:06:20.080 --> 00:06:22.850
So here the user wants to search for recipes,

134
00:06:22.850 --> 00:06:26.590
so that they can find new ideas for meals.

135
00:06:26.590 --> 00:06:28.360
Then, next up,

136
00:06:28.360 --> 00:06:29.927
the next user story is,

137
00:06:29.927 --> 00:06:32.777
"As a user, I want to be able to update,

138
00:06:32.777 --> 00:06:36.307
"the number of servings, so that I can cook a meal,

139
00:06:36.307 --> 00:06:38.690
"for different number of people."

140
00:06:38.690 --> 00:06:41.240
And that of course, makes a lot of sense

141
00:06:41.240 --> 00:06:44.160
in any application of this kind.

142
00:06:44.160 --> 00:06:48.497
Then, next. "As a user, I want to bookmark recipes,

143
00:06:48.497 --> 00:06:51.060
"so that I can review them later."

144
00:06:51.060 --> 00:06:53.330
And again, this really makes sense

145
00:06:53.330 --> 00:06:57.170
in any kind of real world application like this.

146
00:06:57.170 --> 00:06:58.397
Then, "As a user,

147
00:06:58.397 --> 00:07:01.657
"I want to be able to create my own recipes,

148
00:07:01.657 --> 00:07:04.577
"so that I can have all my recipes organized

149
00:07:04.577 --> 00:07:06.850
"in the same application."

150
00:07:06.850 --> 00:07:08.977
And finally, "As a user,

151
00:07:08.977 --> 00:07:13.147
"I want to be able to see my bookmarks and my own recipes,

152
00:07:13.147 --> 00:07:16.797
"when I leave the application and come back later.

153
00:07:16.797 --> 00:07:17.997
"And so this way,

154
00:07:17.997 --> 00:07:22.190
"I can close the application safely, after cooking."

155
00:07:22.190 --> 00:07:26.330
All right, and once again, let's kind of pretend,

156
00:07:26.330 --> 00:07:29.050
that we came up with all these user stories,

157
00:07:29.050 --> 00:07:32.900
while kind of brainstorming for this application.

158
00:07:32.900 --> 00:07:35.840
And so now, we can use all these user stories,

159
00:07:35.840 --> 00:07:39.120
for our next step and come up with the features,

160
00:07:39.120 --> 00:07:41.640
that we need in the application.

161
00:07:41.640 --> 00:07:45.650
So first, the user wants to search for recipes.

162
00:07:45.650 --> 00:07:46.550
And so therefore,

163
00:07:46.550 --> 00:07:50.330
our application should have a search functionality.

164
00:07:50.330 --> 00:07:52.390
Which is basically an input field,

165
00:07:52.390 --> 00:07:53.960
which will send requests,

166
00:07:53.960 --> 00:07:57.620
to an API, with the searched keywords.

167
00:07:57.620 --> 00:08:01.610
Then the application, should of course display these results

168
00:08:01.610 --> 00:08:05.500
and also with pagination, to make it more user-friendly,

169
00:08:05.500 --> 00:08:07.513
in case that there are many results.

170
00:08:09.866 --> 00:08:11.560
And then of course, the application, needs to display

171
00:08:11.560 --> 00:08:14.900
the selected recipe, with relevant data,

172
00:08:14.900 --> 00:08:18.763
such as cooking time, servings and ingredients.

173
00:08:19.630 --> 00:08:22.930
Now the next user story is pretty simple,

174
00:08:22.930 --> 00:08:27.230
so all we need, is a functionality, to change the servings.

175
00:08:27.230 --> 00:08:29.600
So basically updating all ingredients,

176
00:08:29.600 --> 00:08:32.930
according to the current number of servings.

177
00:08:32.930 --> 00:08:35.710
Then, in order to bookmark recipes,

178
00:08:35.710 --> 00:08:39.163
we simply need, a functionality for that.

179
00:08:40.580 --> 00:08:43.490
So basically, allowing users to bookmark the recipe

180
00:08:43.490 --> 00:08:45.860
and then display a list of all of them,

181
00:08:45.860 --> 00:08:48.120
somewhere on the page.

182
00:08:48.120 --> 00:08:49.980
Then for the next user story,

183
00:08:49.980 --> 00:08:52.690
what we need is basically a feature,

184
00:08:52.690 --> 00:08:56.410
that allows users to upload there own recipes.

185
00:08:56.410 --> 00:08:59.430
Which should then automatically get bookmarked,

186
00:08:59.430 --> 00:09:03.823
so that the user, can easily find all of their own recipes.

187
00:09:04.850 --> 00:09:07.760
Now, what's important here, is that each user,

188
00:09:07.760 --> 00:09:10.310
can only see their own recipes

189
00:09:10.310 --> 00:09:13.840
but not the recipes from other users.

190
00:09:13.840 --> 00:09:16.160
And, we could go ahead and implement this

191
00:09:16.160 --> 00:09:18.350
in a very complex way, like,

192
00:09:18.350 --> 00:09:20.770
for example, creating user accounts,

193
00:09:20.770 --> 00:09:22.660
but we will keep it very simple

194
00:09:22.660 --> 00:09:26.830
and basically, simply associate uploaded recipes,

195
00:09:26.830 --> 00:09:28.620
to an API key.

196
00:09:28.620 --> 00:09:31.160
And again, we will see by the end of the section,

197
00:09:31.160 --> 00:09:33.410
how that is going to work.

198
00:09:33.410 --> 00:09:36.233
Now finally, we are going to need a feature,

199
00:09:36.233 --> 00:09:38.340
that will store bookmark data

200
00:09:38.340 --> 00:09:41.500
in the browser using local storage.

201
00:09:41.500 --> 00:09:43.690
And that we already did before

202
00:09:43.690 --> 00:09:47.440
and so this part is gonna be fairly simple.

203
00:09:47.440 --> 00:09:50.560
Then to finish, whenever the page loads,

204
00:09:50.560 --> 00:09:53.670
we need to then read all the saved bookmarks

205
00:09:53.670 --> 00:09:56.800
and display them somewhere on the page.

206
00:09:56.800 --> 00:09:59.940
Great, and with this, we now know exactly,

207
00:09:59.940 --> 00:10:02.140
what we need to implement.

208
00:10:02.140 --> 00:10:06.460
But now, let's take this list, of unstructured features

209
00:10:06.460 --> 00:10:10.070
and actually put it, into a nice structured flowchart,

210
00:10:10.070 --> 00:10:11.710
which will allow us to plan,

211
00:10:11.710 --> 00:10:15.063
how exactly the application, is actually gonna work.

212
00:10:16.810 --> 00:10:18.150
So we're going to start,

213
00:10:18.150 --> 00:10:20.950
only with these first three features,

214
00:10:20.950 --> 00:10:23.080
in order to keep it simple now

215
00:10:23.080 --> 00:10:26.650
and not overwhelm you right from the start.

216
00:10:26.650 --> 00:10:30.110
So, we're gonna build this flowchart, in three parts

217
00:10:30.110 --> 00:10:33.230
and now starting with these three features.

218
00:10:33.230 --> 00:10:36.450
And as always, we're going to focus on events

219
00:10:36.450 --> 00:10:39.270
and the first event in our web application,

220
00:10:39.270 --> 00:10:43.370
should probably be, the user searching for a recipe.

221
00:10:43.370 --> 00:10:47.200
And so that's our feature number one, basically.

222
00:10:47.200 --> 00:10:50.660
So, when a user searches for a certain recipe,

223
00:10:50.660 --> 00:10:52.830
then we need to asynchronously,

224
00:10:52.830 --> 00:10:56.420
load the search results from our API,

225
00:10:56.420 --> 00:10:59.670
and so of course that happens asynchronously,

226
00:10:59.670 --> 00:11:01.900
and then once the results are in,

227
00:11:01.900 --> 00:11:05.430
we will simply render them in our application.

228
00:11:05.430 --> 00:11:08.520
However, we will not render all the search results,

229
00:11:08.520 --> 00:11:12.060
right away, because that would be overwhelming.

230
00:11:12.060 --> 00:11:16.040
And so instead, we also render some pagination buttons,

231
00:11:16.040 --> 00:11:19.780
in order to hide, basically part of the search results

232
00:11:19.780 --> 00:11:21.760
on different pages.

233
00:11:21.760 --> 00:11:24.550
So, that makes sense. Right?

234
00:11:24.550 --> 00:11:28.430
And then as a user clicks one of the pagination buttons,

235
00:11:28.430 --> 00:11:30.640
it will then render the search results,

236
00:11:30.640 --> 00:11:34.020
for the new page that was selected basically

237
00:11:34.020 --> 00:11:37.460
and it will also render new pagination buttons.

238
00:11:37.460 --> 00:11:40.030
So for example, when we're on page two,

239
00:11:40.030 --> 00:11:43.110
then there will be a button, to go back to page one

240
00:11:43.110 --> 00:11:45.890
and a button to go to page three.

241
00:11:45.890 --> 00:11:47.810
But when we're on page three,

242
00:11:47.810 --> 00:11:50.890
then the button to go back will point to page two

243
00:11:50.890 --> 00:11:54.800
and the button to go forward, will point to page four.

244
00:11:54.800 --> 00:11:57.090
And so we need to rerender these buttons,

245
00:11:57.090 --> 00:11:59.870
basically, every time that a user clicks

246
00:11:59.870 --> 00:12:01.793
on one of them. Right?

247
00:12:02.820 --> 00:12:05.110
Then, finally, we also need a logic,

248
00:12:05.110 --> 00:12:07.453
to actually display the recipe.

249
00:12:08.290 --> 00:12:10.940
So when the user selects a recipe,

250
00:12:10.940 --> 00:12:13.440
then, we need to asynchronously load,

251
00:12:13.440 --> 00:12:16.200
all the recipe data from the API

252
00:12:16.200 --> 00:12:18.060
and then once the data arrived,

253
00:12:18.060 --> 00:12:21.560
we render the recipe, to the user interface.

254
00:12:21.560 --> 00:12:24.100
And we will actually also do the same,

255
00:12:24.100 --> 00:12:26.090
whenever the page loads,

256
00:12:26.090 --> 00:12:29.260
with a recipe ID, in the URL.

257
00:12:29.260 --> 00:12:30.890
So, I think I showed you that

258
00:12:30.890 --> 00:12:33.140
in the beginning of this video.

259
00:12:33.140 --> 00:12:35.699
So whenever we click on a recipe,

260
00:12:35.699 --> 00:12:39.460
then the URL will change, with the recipe ID.

261
00:12:39.460 --> 00:12:42.950
Remember that. And so it's important that,

262
00:12:42.950 --> 00:12:47.420
for example, if we take that URL and copy it and paste it,

263
00:12:47.420 --> 00:12:49.133
for example, to another browser,

264
00:12:50.160 --> 00:12:52.350
that then the recipe corresponding to that ID,

265
00:12:52.350 --> 00:12:54.750
should also load right away.

266
00:12:54.750 --> 00:12:57.150
And so that's why, here in this flowchart,

267
00:12:57.150 --> 00:13:00.740
I have the Load recipe on both events.

268
00:13:00.740 --> 00:13:04.430
So, when the user selects a recipe from the user interface,

269
00:13:04.430 --> 00:13:06.840
or also when the page loads,

270
00:13:06.840 --> 00:13:10.760
with a recipe ID, already in the URL.

271
00:13:10.760 --> 00:13:12.930
All right, and that's actually it,

272
00:13:12.930 --> 00:13:16.200
for part one, of the flowchart.

273
00:13:16.200 --> 00:13:18.020
And in fact, these are basically,

274
00:13:18.020 --> 00:13:20.380
already, all core features,

275
00:13:20.380 --> 00:13:23.570
so the most important features, of the application

276
00:13:23.570 --> 00:13:27.640
So searching for recipes, rendering search results

277
00:13:27.640 --> 00:13:29.030
and then also rendering,

278
00:13:29.030 --> 00:13:32.700
the individual recipe that was selected.

279
00:13:32.700 --> 00:13:35.330
And so all these, will probably take us,

280
00:13:35.330 --> 00:13:37.890
half of the section to implement.

281
00:13:37.890 --> 00:13:40.980
So there really is, a lot to do.

282
00:13:40.980 --> 00:13:43.970
Now, we will start implementing the project,

283
00:13:43.970 --> 00:13:46.330
only with the recipe displaying.

284
00:13:46.330 --> 00:13:48.830
So only feature number three,

285
00:13:48.830 --> 00:13:52.960
which is basically this right part of the flowchart.

286
00:13:52.960 --> 00:13:54.460
And this will allow us,

287
00:13:54.460 --> 00:13:57.470
to start implementing some functionality

288
00:13:57.470 --> 00:14:00.660
and also play around with the application a little bit,

289
00:14:00.660 --> 00:14:03.920
but still without thinking, about the architecture.

290
00:14:03.920 --> 00:14:06.390
And so without the rigid structure,

291
00:14:06.390 --> 00:14:09.710
that might be imposed, by architecture.

292
00:14:09.710 --> 00:14:11.500
Great. So with this,

293
00:14:11.500 --> 00:14:15.160
we basically have this part of the application planned

294
00:14:15.160 --> 00:14:18.023
and so let's now finally get to work.

