Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
1 1
So after loading the recipe data 2
2
from or API, let's now render that data in our application. 3
3
And for that, let's go 4
4
to our HTML file to basically get the template from there. 5
5
Let's close down this terminal 6
6
which will keep working in the background. 7
7
And so here is the results part, the pagination. 8
8
And then here we have the recipe class. 9
9
So the recipe class 10
10
is basically this whole container. 11
11
So here in this case, 12
12
it's this whole gray container 13
13
which is the one that will contain 14
14
the rendered recipe. 15
15
Okay. 16
16
Then right now it has that message. 17
17
So again, it is this message here 18
18
that is already rendered there at this point. 19
19
Then here's the code for a loading spinner 20
20
for an error 21
21
and then here, actually for the recipe itself. 22
22
So here we have that, not that image, 23
23
and then all of the information about the recipe itself. 24
24
And so it's all of this code that we need now. 25
25
So let's grab 26
26
all of this commented out code 27
27
and copy it 28
28
and paste it here into this function. 29
29
So let's add a comment here. 30
30
So loading recipe 31
31
and then afterwards as step number two, 32
32
rendering the recipe. 33
33
And for now here we are doing this 34
34
like really big function. 35
35
But of course, 36
36
once we start thinking about the architecture 37
37
we will then break this up 38
38
into functions and modules 39
39
and classes and so on and so forth. 40
40
And so, as always doing a big 41
41
template literal here, just as always, 42
42
so that we can 43
43
and then replace all the data here 44
44
that we need. 45
45
Just fixing the indentation here now. 46
46
And so now let's take all the data that we need. 47
47
And the first one here is the image. 48
48
So let's replace this string here 49
49
with recipe.image. 50
50
Just like we specified here. 51
51
And so this image property 52
52
is basically a URL, 53
53
which points to the location of the image 54
54
on the Forkify API server. 55
55
Then here we have the recipe title. 56
56
So this one here, 57
57
.title. 58
58
And actually we also have that title here 59
59
as an alt text of the image. 60
60
Okay. 61
61
Then here we have the clock. 62
62
So this 45 here is the cooking time. 63
63
So recipe 64
64
and missing the block here, 65
65
.cookingTime. 66
66
Then down here, we have servings. 67
67
And so that's this number here. 68
68
So number four will now be replaced 69
69
with the data coming from the recipe object, 70
70
recipe.servings 71
71
and let's keep going. 72
72
So down here, we have the ingredients. 73
73
So for each ingredient, 74
74
there will be one list element of this. 75
75
So this example, 76
76
right now we have two list elements 77
77
and one for each ingredient. 78
78
But let's actually keep that for later. 79
79
And for now keep filling the rest 80
80
of the data here. 81
81
So this is the next piece of data, 82
82
which is the publisher. 83
83
So here it says recipe publisher. 84
84
And so let's change that 85
85
to recipe.publisher. 86
86
Then here we have the source URL. 87
87
So let's take a look at that, 88
88
maybe here to make more sense of this. 89
89
So we used most of this data here already. 90
90
So here is the URL to the recipe itself, 91
91
where it actually comes from. 92
92
And then about the ingredients, 93
93
as you see, it is one array 94
94
and each position of the array contains one object 95
95
which contains the quantity, 96
96
the unit and the description of each ingredient. 97
97
And so we will have to basically loop 98
98
over this array 99
99
and then use all of this data 100
100
to create one list element for each of them. 101
101
Okay. 102
102
But for now, let's go back 103
103
and finish the data here. 104
104
And in this case, 105
105
replacing this URL 106
106
by the one coming from the object. 107
107
So that's the recipe 108
108
that source URL. 109
109
And so except for the ingredients, 110
110
that's actually it. 111
111
So yeah, before we can check out the result, 112
112
of course now we need 113
113
to actually insert this HTML into our dump. 114
114
So for that, we can use the insert adjacent HTML method 115
115
and we need to do that 116
116
on the parent element, 117
117
remember. 118
118
And I already selected that up here. 119
119
So remember, that's the element 120
120
with the class of recipe. 121
121
So just to remember, it is this diff element. 122
122
So that is called a recipe container. 123
123
And so that's where we want to attach 124
124
this HTML markup. 125
125
So recipeContainer.insertAdjacentHTML, 126
126
and let's do afterbegin. 127
127
So basically as a first child 128
128
and then the markup variable 129
129
that we just created 130
130
and that should be it. 131
131
So this should now render the recipe 132
132
in the user interface 133
133
except for the ingredients. 134
134
And indeed, that's looking really nice already. 135
135
Right? 136
136
So the ingredients are still the old ones 137
137
but the rest is really nice, 138
138
except for that we have still 139
139
this message here from the beginning 140
140
and also that we are missing all the icons. 141
141
So you see there are no icons to be found here. 142
142
In the real one, of course, 143
143
there are icons all over the place. 144
144
So we have three problems here. 145
145
We have this message showing 146
146
we have the ingredients 147
147
and we have the icons. 148
148
And let's start with this message 149
149
and then the ingredients. 150
150
So before we insert any new markup 151
151
we need to get rid 152
152
of the markup that is already there. 153
153
So let's simply do recipeContainer.innerHTML 154
154
and set it to nothing. 155
155
So emptying it out. 156
156
And so you see now it is gone. 157
157
All right. 158
158
So let's now worry about the ingredients. 159
159
And again, we will need to loop 160
160
over the ingredients array. 161
161
And for each of them, 162
162
we should then create this kind of markup here. 163
163
So how should we do that? 164
164
Well, basically exactly what I just said. 165
165
So we take recipe.ingredients 166
166
and then we loop over that using some array method. 167
167
But what array method should we actually use? 168
168
Well, remember that in the end 169
169
the expression that we need here 170
170
needs to return a string of HTML. 171
171
And so that means 172
172
that or array method needs to return something. 173
173
So foreach is not the way to go here. 174
174
So not foreach. 175
175
Right? 176
176
But instead we are going to use map. 177
177
So map returns a new array 178
178
with the same length. 179
179
And so that array, we will then in the end, 180
180
be able to simply join. 181
181
And so now we can loop 182
182
over the array 183
183
by specifying a callback function. 184
184
So each element is going to be called ingredient 185
185
and then here we can do something. 186
186
So let's simply replace a string here. 187
187
Right? 188
188
So taking this 189
189
and put it right here. 190
190
And then of course we don't need 191
191
this one anymore. 192
192
(clicking) 193
193
Okay. 194
194
Then here we have some kind of error, 195
195
but nevermind. 196
196
Let's think about the data here first. 197
197
So let's take a look 198
198
at the data actually again. 199
199
So at the array. 200
200
So each array element is an object 201
201
which has quantity, 202
202
unit and description. 203
203
Okay. 204
204
So this ingredient is now that object. 205
205
And so here we can say 206
206
ingredient.quantity 207
207
then here the unit, 208
208
the ingredient.unit 209
209
and then finally here 210
210
instead of pasta we want 211
211
the ingredient.description. 212
212
And so now here 213
213
we will have an array 214
214
in which each element 215
215
will contain this markup corresponding 216
216
to the ingredient. 217
217
And so now all we need to do 218
218
is to transform that array of strings 219
219
into one big string. 220
220
So we can take the result of this map, 221
221
which is that array 222
222
and call join on it like this. 223
223
And so now the result of this entire expression 224
224
is going to be 225
225
a big string containing all the ingredients. 226
226
So if we give it a save now, 227
227
then indeed here we have our eight ingredients. 228
228
Okay. 229
229
So that's pepperoni pizza burgers. 230
230
And now, 231
231
remember we have a second one here, 232
232
so that's, switched them out again. 233
233
Give it a save. 234
234
And now we got, 235
235
well, this pizza here. 236
236
And so indeed it now has different ingredients, 237
237
different publisher 238
238
and everything is different. 239
239
Great. 240
240
But now there is one thing missing, 241
241
which is the icons. 242
242
So let's see why that is. 243
243
Well, remember that the page that 244
244
is displayed here in the browser, 245
245
is this HTML here from the disc folder. 246
246
Right? 247
247
And so remember that all the images 248
248
and really all the assets 249
249
are now coming from this folder. 250
250
And that includes the icons. 251
251
So our icons are always coming 252
252
from this icon.svg file. 253
253
But now the icons are actually coming 254
254
from icons.all of this here. 255
255
And you can see that 256
256
for example, 257
257
right here in the search bar. 258
258
So icon search is coming 259
259
from icons.96 and so on and so forth. 260
260
However, in our template literal, 261
261
we are still writing, basically, 262
262
the old path to the icons. 263
263
So this one here. 264
264
And so right now, 265
265
JavaScript will not be able to find this. 266
266
So in the disc folder, 267
267
this one here, 268
268
there is no source/image folder 269
269
in which there is icons.svg 270
270
because that exists only 271
271
in our source folder. 272
272
So only right here 273
273
where we are developing the application. 274
274
But again right now 275
275
we are basically shipping the application already. 276
276
And so it's using the data from this disc folder. 277
277
And so now we need a way 278
278
of telling our JavaScript 279
279
that the icons file is no longer this one 280
280
but instead it is this one. 281
281
And we can actually do that 282
282
with parcel by basically simply importing 283
283
the icons file. 284
284
So let's go to the top of our file 285
285
because I like to keep all the imports 286
286
always at the top. 287
287
And so again, in parcel, 288
288
we can import more than just JavaScript files. 289
289
We can import all kinds of assets 290
290
and that includes images. 291
291
So let's import 292
292
and let's call it simply icons. 293
293
But this name can be anything that we want. 294
294
(clicking) 295
295
From another path to the original icons file, 296
296
basically, from the view of this controller file, 297
297
right? 298
298
So here we are in controller.js. 299
299
And so now we need to find a path 300
300
to the images, 301
301
so to this original icons file. 302
302
So we need to go one way up. 303
303
So exactly the way we browse 304
304
the file tree in the terminal. 305
305
So .. always means the parent folder. 306
306
And so right now we are back 307
307
in the source folder, 308
308
which is the parent of js. 309
309
And then from there, 310
310
we can go into images 311
311
and then icons.svg. 312
312
All right. 313
313
Now this is the way it used to work 314
314
in parcel one. 315
315
So if for some reason, 316
316
you are running parcel one 317
317
then this is the way to go. 318
318
But in parcel two, 319
319
it works almost the same way. 320
320
But then for any static assets 321
321
that are not programming files. 322
322
So for any like images 323
323
or videos or sound files, 324
324
we need to write url: 325
325
and then the path to the file. 326
326
Okay. 327
327
So let's take this out 328
328
but then let's lock this icons to the console 329
329
so that you see what this icons really is. 330
330
Because in fact, it is nothing more 331
331
than simply the path to the new icons file. 332
332
So the local host, 333
333
one two, three, four 334
334
is in this case, basically, 335
335
our disc folder. 336
336
And then in there, 337
337
the file that we need is icon.96f 338
338
and so on and so forth. 339
339
And so that is exactly this file here. 340
340
Okay. 341
341
And so now let's use that. 342
342
So everywhere it says icon. 343
343
So everywhere we have this old path 344
344
we now want to replace it simply with the icons. 345
345
So let's select all of them using command 346
346
or Control+D. 347
347
Or if that doesn't work for you, 348
348
you can always probably use Command+F 349
349
or something like that. 350
350
But anyway, 351
351
now we have all of them selected at the same time 352
352
and then I can delete them all 353
353
and then insert the icons variable here everywhere. 354
354
And so now if we give this a save 355
355
then our icons are back. 356
356
Right? 357
357
So starting here 358
358
then in all ingredients 359
359
and here also, 360
360
all over the place. 361
361
We now have our icons back. 362
362
And now just to finish this lecture, 363
363
I want to give this one more touch, 364
364
which is this here. 365
365
So watch what happens here 366
366
in the recipe when I load the page. 367
367
Well, that was pretty fast. 368
368
Let's see again. 369
369
So maybe for half a second or so 370
370
you saw a loading spinner there. 371
371
And so that's what I want to have here as well. 372
372
So before the recipe arrives 373
373
I want like a loading spinner there 374
374
because that's a very common pattern 375
375
that you see in all kinds of applications. 376
376
Right? 377
377
And it's actually very simple. 378
378
So we have the code already here 379
379
in our HTML. 380
380
So it is this a spinner here. 381
381
So let's grab this code. 382
382
And then 383
383
here I will simply create an external function 384
384
called 385
385
render a spinner 386
386
and let's make this a very generic function 387
387
that we can reuse. 388
388
And so that's passed in the parent element. 389
389
And so then we can simply attach this 390
390
to any parent element 391
391
that is passed in here. 392
392
So as always creating a markup variable 393
393
and then our code here. 394
394
And just like before, 395
395
we need to now replace this old path 396
396
with the new path. 397
397
So icons 398
398
and then of course, 399
399
we need to add this HTML 400
400
to the dump as a child 401
401
of the parent element in this case. 402
402
So parentEl.insertAdjacentHTML 403
403
afterbegin 404
404
and markup. 405
405
Okay. 406
406
And now let me just quickly show you 407
407
why this is going to work. 408
408
So here in the CSS, 409
409
let's look for spinner. 410
410
And here you see 411
411
that the icon inside of the spinner class 412
412
has this rotation animation 413
413
that keeps going forever. 414
414
So that's this infinite attribute here 415
415
in the animation property. 416
416
And this rotation animation 417
417
I created here manually using key frames. 418
418
And basically what it does 419
419
is to rotate the element 420
420
to 360 degrees. 421
421
And so if you ever need a spinner like this, 422
422
you can simply, basically copy this code here. 423
423
All right. 424
424
Let's close what we don't need here. 425
425
And probably, before we insert this, 426
426
we should also clear the parent element. 427
427
So just like before setting the inner HTML 428
428
to nothing. 429
429
And now let's actually render the spinner. 430
430
So let's do that here 431
431
as we load the recipe. 432
432
So right here. 433
433
So renderSpinner 434
434
and then the parent element in this case, 435
435
is going to be the recipeContainer. 436
436
All right, let's go back 437
437
and reload 438
438
and there it was. 439
439
You saw it. 440
440
Let's make this a little bit slower 441
441
by changing our network speed here. 442
442
So it took a little bit longer, 443
443
maybe slow 3G 444
444
is gonna be even better. 445
445
And so now it's gonna take 446
446
a lot more time 447
447
but indeed here it is. 448
448
So that spinner is a nice touch, 449
449
I think. 450
450
And it definitely makes this application 451
451
feel more real world. 452
452
Now just to finish this video, 453
453
something that I should have done 454
454
in the last video already 455
455
is to add polyfills 456
456
for es6 features 457
457
to our code base. 458
458
So just like we did 459
459
in the previous section as well. 460
460
So remember to do that, 461
461
we installed some special packages. 462
462
So the packages are called npm core-js 463
463
and we can actually install multiple packages 464
464
at the same time. 465
465
I think I never did this before. 466
466
So this is how it works. 467
467
Regenerator-runtime 468
468
and then hit enter 469
469
and then let's wait for these packages to download 470
470
and here they are. 471
471
So they should be, 472
472
yeah, 473
473
so right here 474
474
and now all we have to do 475
475
is to import them here 476
476
at the top of our file. 477
477
And so it is, we make sure 478
478
that most real old browsers 479
479
are still being supported 480
480
by our application. 481
481
So actually we don't even need to save it anywhere. 482
482
We can just say core-js/stable. 483
483
So vs code, one more time, is really smart 484
484
and can really help us 485
485
with package imports like this. 486
486
So again, this one here 487
487
is for polyfilling async/await. 488
488
And this one here is for polyfilling everything else. 489
489
And we could just cherry pick some features 490
490
and only import those 491
491
but let's simply polyfill everything. 492
492
Okay. 493
493
Don't need this terminal anymore. 494
494
This one here already reload it 495
495
and you see everything keeps working the same. 496
496
All right. 497
497
So we have this working. 498
498
Now in the next video, 499
499
let's quickly add some event handlers 500
500
so that after that 501
501
we can start talking about the architecture.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.