All language subtitles for 17. Updating Recipe Servings

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

1 1

Okay, so let's now implement 2

2

the feature of updating recipe servings. 3

3

And this time, we're actually starting in the controller, 4

4

just so we can outline what we want to happen. 5

5

So let's come down here and add yet another controller. 6

6

So control servings, let's say. 7

7

And I keep calling these functions here, controllers, 8

8

but that's just because we're using 9

9

the model view controller pattern. 10

10

So they could also be called handlers, because in the end, 11

11

that's what they are, they are simply event handlers, 12

12

that will run whenever some event happens. 13

13

Now, in this case, this controller here 14

14

will eventually be executed when the user clicks 15

15

on one of these buttons here. 16

16

So either to decrease, or to increase the servings. 17

17

And so that will then increase or decrease this number here, 18

18

and also adjust all of these ingredients, right? 19

19

So this controller is actually going to be very simple. 20

20

All we have to do here is to update the recipe servings, 21

21

so in the state. 22

22

So basically updating the underlying data. 23

23

And then all we have to do is to update the view as well. 24

24

So actually updating the recipe view, 25

25

because that is of course, the view that will be impacted 26

26

by controlling the servings, right? 27

27

So in this case, we will actually have no, 28

28

like servings view, because these buttons, 29

29

and everything that happens when we click on them 30

30

is already in the recipe view, all right? 31

31

So here, updating the servings in the state 32

32

has of course to do with the model. 33

33

And so in the model, we would like to have 34

34

some method which does that for us. 35

35

So as always, we will not want to manipulate data 36

36

directly here in a controller, 37

37

instead we delegate that task to the model, 38

38

which is all about the data. 39

39

So again, in the model, we will like to have 40

40

a method called update servings, 41

41

and then we can pass in the new servings. 42

42

So let's just say six here, for experimenting. 43

43

And so let's, now go to the model 44

44

and actually implement this. 45

45

So load recipe, then results, 46

46

then here, we will have the update servings function. 47

47

And so this will then take in the number of servings, 48

48

let's call it new servings, actually. 49

49

Now what this function will do is to reach into the state, 50

50

and in particular into the recipe ingredients, 51

51

and then change the quantity in each ingredient. 52

52

So we have state.recipe, 53

53

and then we have that ingredients array, ingredients. 54

54

And so again, in each ingredient, 55

55

we now want to change the quantity property. 56

56

So just to remember, again, our data, because I know 57

57

this can be quite confusing, let's do a search here, 58

58

because that will then change us, 59

59

or actually it will show us here some real data. 60

60

So here is a recipe. 61

61

Ah, this is actually only the search data. 62

62

But this is the actual data here, so for the entire recipe. 63

63

And so remember that we have two ingredients in there 64

64

and each ingredient is an object, 65

65

which contains the quantity. 66

66

And so this is the quantity we want to change. 67

67

For example, here this quantity two is four four servings, 68

68

but if we had eight servings, 69

69

then the quantity should become eight, right? 70

70

So the servings doubled, 71

71

and so the quantity needs to double as well. 72

72

And so that's the kind of logic that we will write now. 73

73

And so, yeah, this was just to show you 74

74

that it is the quantity property 75

75

inside of the ingredient that we will want to mutate. 76

76

So we want to do something for each of these ingredients. 77

77

So we don't want a new array, and we could do that also. 78

78

So we could create a new array, 79

79

and then override state.recipe. 80

80

But let's just do it like this. 81

81

So basically with side effects. 82

82

So in each iteration of the loop, 83

83

we have the current ingredient. 84

84

And then here, we want to do something with it. 85

85

So basically, we want to change it. 86

86

So ingredients.quantity, should become something new. 87

87

And now how do we calculate this new quantity? 88

88

Well, we will basically use this formula. 89

89

So let me write that here. 90

90

So new quantity equals the old quantity 91

91

times the new servings divided by the old servings. 92

92

And let's use the example that I mentioned earlier. 93

93

So changing from four servings to eight servings. 94

94

And I think we had the quantity of two. 95

95

So two times, and then the new servings again, 96

96

were eight divided by four. 97

97

And so this would then be eight divided by four is two, 98

98

times two is four. 99

99

So again, if we double the servings like this, 100

100

then we also need to double the quantity. 101

101

So we then multiply the original quantity 102

102

by this ratio here, basically. 103

103

Now okay, so just basic mathematics here. 104

104

And so let's not put this formula here. 105

105

So the old quantity is in this case, 106

106

also ingredients.quantity, so the original one, 107

107

and then times the new servings. 108

108

So the one we are getting here, 109

109

divided by state.recipe.servings, now, okay. 110

110

So with this, we are changing all the ingredients. 111

111

In order to finish, of course, 112

112

we also need to update the servings in the state. 113

113

Because otherwise, if we tried to update the servings twice, 114

114

then by the second time, we would still be using 115

115

the old value of two servings. 116

116

And so of course, we need to update this value. 117

117

So state.recipe.servings, needs to be the new servings. 118

118

And we're doing that here at the end of the function, 119

119

because otherwise, we could not preserve this old. 120

120

So this original value here, okay? 121

121

So this, we update the servings of the current recipe. 122

122

And again, that works because we already have 123

123

the recipe in the state. 124

124

Okay, and so then we need to simply update the recipe view. 125

125

And by now what we will do is to actually simply overwrite 126

126

the complete recipe. 127

127

So basically, we will simply render it again. 128

128

So exactly what we had here actually, in control recipes. 129

129

So taking the recipe out of the state, 130

130

and then simply rendering it. 131

131

So let's copy this down here. 132

132

So we do that, because we don't want to 133

133

like manually go ahead and 134

134

change all these values here one by one. 135

135

So we would have to select this element and this element, 136

136

and this one, and then manually change all of that. 137

137

And the same here for this value, right? 138

138

And so we don't want to have all of that work. 139

139

And so for now, we will simply, 140

140

well update this entire element here again, 141

141

so this entire view, okay? 142

142

And now let's actually call this controller here, 143

143

without having to create the event listener just yet. 144

144

So just to test if everything is working. 145

145

And so let's do that, after all of this. 146

146

So here in the init function at the end, 147

147

we call control servings. 148

148

And so with this, we can guarantee 149

149

that there is already a recipe loaded. 150

150

So let's actually use the example of eight here 151

151

so that we double the values. 152

152

Not well, that's not really working. 153

153

There seems to be some kind of bug here. 154

154

Oh, and for each is of course, wrong here. 155

155

But we also have some other problem here apparently, 156

156

which is that we are trying to read for each on undefined. 157

157

So let's first fix that small error. 158

158

So it's called for each. 159

159

And then that other problem actually comes from the fact 160

160

that we are doing it wrong. 161

161

So we are not taking into account the asynchronous nature 162

162

of our application here. 163

163

So, basically, here, we are trying to control the servings 164

164

simply after registering these handler functions here. 165

165

But by that time, no recipe has yet arrived from the API. 166

166

And so therefore, state.recipe is not yet defined. 167

167

And so here we are then trying to read ingredients 168

168

from the recipe that doesn't exist, okay? 169

169

Does that make sense? 170

170

And this is actually a great demonstration of the pitfalls 171

171

of working with Asynchronous JavaScript. 172

172

So if we really wanted to test this here right now, 173

173

we could probably do that right here, 174

174

after we control the recipes. 175

175

So basically, after the recipe is loaded. 176

176

So let's just temporarily put this here, 177

177

or probably even better, right here. 178

178

Let's just mark this very clearly as a test, all right? 179

179

And let's see what happens now. 180

180

Oh, and now we have the eight servings that we want. 181

181

And here, these values, they should have changed. 182

182

Well, I'm not sure what they looked like before. 183

183

But we can reach here now, 184

184

but here we also already have the eight servings. 185

185

So this is not a good comparison. 186

186

But let's try it here with four. 187

187

And so we have four. 188

188

And yeah, these values are actually half 189

189

of what they were before. 190

190

And so that means that our update servings function 191

191

is already doing its job, so that's great. 192

192

So we can remove that from here 193

193

because now we will actually want the controller to run 194

194

whenever we click one of the buttons in the recipe view. 195

195

And so what we will do now is to create 196

196

a new event listener in the recipe. 197

197

So here in this recipe view. 198

198

And again, that's because that's 199

199

where these buttons already are. 200

200

And so there is no need to create a new, like servings view. 201

201

So here, I will simply create a new method. 202

202

And as always, it's called add handler and then something. 203

203

So here, let's call it update servings, 204

204

to make its purpose really clear 205

205

and then as always the handler function. 206

206

And again, that handler function will of course, 207

207

then be debt controller that we just wrote here, okay? 208

208

Now, how will we actually do this? 209

209

So the parent element here is this whole recipe, 210

210

but the elements that we are interested in, 211

211

are these two buttons. 212

212

So these buttons increase servings, 213

213

end button decrease servings. 214

214

And the class that they have both in common, 215

215

is this button tiny, right 216

216

Now, each of these buttons also 217

217

has some elements inside of it. 218

218

And so yeah, the best way of doing this 219

219

is actually once again, doing event delegation. 220

220

So we already have the parent element. 221

221

And so we can listen for events on that one. 222

222

And then check if the click target was one of those buttons. 223

223

And so this is actually going to be very similar 224

224

to what we did in the last video 225

225

with the pagination buttons. 226

226

So add event listener, click. 227

227

And then here again, we want to actually select 228

228

that button element that was clicked or not. 229

229

So here we then use again, event.target, 230

230

which is the clicked element. 231

231

And then once again, we use the closest method, 232

232

which is, I think I've said it before, an amazing method, 233

233

which is really, really useful for event delegation. 234

234

And so again, we are looking for 235

235

elements with the button tiny class. 236

236

So button tiny and that is important because 237

237

the user might click, actually on this. 238

238

So on this SVG element instead of the button element itself, 239

239

and so then that will basically look 240

240

for the closest button tiny, right? 241

241

But of course, if we're clicking outside 242

242

of any of these buttons, then this closest 243

243

will not return any element, it will return null. 244

244

And so we need to check for that, just like before. 245

245

So if null button, then return. 246

246

But otherwise, let's simply for now login to the console. 247

247

And so now we need to connect this here with a controller. 248

248

And so let's do that. 249

249

So that's, and let's actually do this here. 250

250

So keep it close to the other recipe view. 251

251

So recipe view.add handler update servings, 252

252

which will then receive control servings, 253

253

so that it can execute our controller function. 254

254

And so if we now put some value here, let's say eight, 255

255

then that should actually already update the servings 256

256

and re render the recipe view. 257

257

So let's see. 258

258

Let's take a look here at this value and these values here. 259

259

Oh, and nothing happened because of course, we didn't call. 260

260

So here, we didn't call control recipes yet, right? 261

261

So we didn't call the handler function. 262

262

But let's actually do that, now, right. 263

263

And you see that the number here change to eight. 264

264

And here all the values changed as well. 265

265

So that's great means again, 266

266

that our update servings function is doing its job. 267

267

And the same can be set for control servings. 268

268

Now, we can also see that 269

269

the correct button here was selected. 270

270

Now it's actually not showing it anymore, here. 271

271

But that's probably because the DOM was re rendered here. 272

272

And so this new button is not exactly 273

273

this button that we have here. 274

274

But that doesn't really matter 275

275

because all I wanted was to check 276

276

if the selection was correct here, and it was. 277

277

So let's try that again now with the increase button, 278

278

and watch again what happens with ingredients, okay? 279

279

And so here, we got the button increased servings. 280

280

Now okay, so we're almost done here. 281

281

Now, all we want to do is, of course, 282

282

to decrease the value when we click here, 283

283

and increase the value when we click the plus button. 284

284

And so we don't want to always set the value to eight, 285

285

but instead, do that dynamically. 286

286

And there are multiple ways in which we can do that. 287

287

So let's think about this a little bit. 288

288

So we could do it right in the controller 289

289

because right here, we already know 290

290

what the current number of servings is. 291

291

And so then here, we could simply take that, 292

292

and decrease or increase that value by one. 293

293

And so that would then yield the effect that we want. 294

294

However, I would like to keep this controller here 295

295

as flexible and as robust as possible. 296

296

And so I don't want this controller 297

297

to be the one responsible for telling, 298

298

which should be the next serving. 299

299

So the next number of servings. 300

300

So that should come from the view, 301

301

and not from the controller, because it is in the view 302

302

where the user is actually updating the servings. 303

303

And so in order to keep this controller 304

304

as flexible as possible, we can simply pass in, 305

305

basically the new servings, 306

306

and then pass that new servings into update servings. 307

307

Okay, so new servings here. 308

308

And then use that here as well. 309

309

And so now we will determine this new servings in the view, 310

310

and pass that value down into this controller, all right? 311

311

But now here in this function, 312

312

how will we determine the new servings? 313

313

Well, once again, here we will need to connect 314

314

the user interface with decode. 315

315

And as always, for that we use the special data properties. 316

316

So let's come to our button or both our buttons 317

317

and then add a new property here. 318

318

And so then we can read the value from that property 319

319

in the Add event listener function. 320

320

So let's say data, update, to. 321

321

And then here the value should be the current servings, 322

322

and plus one, right, because this is the button 323

323

to increase the servings, 324

324

while actually both are called increase, 325

325

but this one has a minus sign. 326

326

So this icon here is called icon minus. 327

327

So that means that we are decreasing the value. 328

328

But anyway, what we want here 329

329

is basically the current servings minus one, right? 330

330

And then in the other button, 331

331

we want the same, but plus one. 332

332

So as I said, in the beginning, 333

333

this is pretty similar to the pagination buttons, 334

334

until let's actually change the increase 335

335

that we have in both to update. 336

336

Okay, and let's then actually use this class 337

337

to select the buttons. 338

338

Because button tiny is a class 339

339

that is actually more about styling, 340

340

and this button update servings 341

341

is more about the functionality, so let's use that one here. 342

342

And so now we can read, now, of course, that value. 343

343

So const update, two equals the button.data set.update to. 344

344

Alright, so here updates two as well. 345

345

And it has this camel case here, 346

346

because when there is a dash in the property name, 347

347

then that will be converted to camelcase notation like this. 348

348

And here, we can actually use destructuring, 349

349

so that makes the code even cleaner. 350

350

Then we can pass that value here to update to, 351

351

and that's it, right? 352

352

Now, here, we just need to convert that to a number, 353

353

but besides that, we should be good to go. 354

354

So it should be working now. 355

355

So instead of changing to the hard coded value of eight 356

356

we had before, let's see what happens now. 357

357

Now we get undefined servings. 358

358

So let's try to understand what's happening. 359

359

But at least the button here was correct. 360

360

So the value used to be four, 361

361

and so the plus button that we clicked 362

362

had the data update to, set to five. 363

363

Okay, so here, let's simply check the value of update to, 364

364

maybe we did something wrong in getting that value. 365

365

Yeah, it looks like there is undefined. 366

366

So let's go back and check what's going on here. 367

367

But it looks correct. 368

368

So update to is not spelled wrong, am I right? 369

369

Update to, man, so, 370

370

well, let's try to get rid of destructuring, 371

371

but that shouldn't be the cause, update to, 372

372

Oh, and actually, that should be the cause 373

373

because of this conversion that we have here. 374

374

So I was trying to convert plus a button data set, 375

375

and then trying to get update to from there. 376

376

So I'm sure that now it will work, but let's see. 377

377

And yes, it does, so now we get the number there. 378

378

So beautiful, and you see the values changing down there. 379

379

And everything works correctly. 380

380

Now there's just this flickering of the image here. 381

381

But we will take care of that in the next lecture. 382

382

For now let's experiment 383

383

and see what happens here at a certain point. 384

384

So here we reach zero servings, 385

385

and then we go even further down. 386

386

And so this of course doesn't make any sense. 387

387

And so we need to add a check here. 388

388

So basically, we only want to call the handler, 389

389

if the number we will update to is greater than zero. 390

390

So we don't want to update to zero or anything below. 391

391

And so then in that case, we simply don't call the handler. 392

392

Okay, now here, let's put it back to the structuring 393

393

like we had it before. 394

394

So I really prefer that. 395

395

And then I will simply do the conversion from the string. 396

396

So right now this is a string. 397

397

So I will simply convert that here, and also here. 398

398

I can also get rid of this console.log here 399

399

to make the function a bit cleaner, and so let's see again. 400

400

So it keeps working here. 401

401

But then as we reach one, it doesn't go any further down. 402

402

Okay, so beautiful, that works. 403

403

But we're still using this kind of hack of updating 404

404

the entire view here at once. 405

405

So remember, here in the controller, 406

406

in order to basically update the recipe view, 407

407

we are simply rendering it all over again. 408

408

And so that takes some time, 409

409

especially noticeable here in the image. 410

410

So you see, I think it's basically trying to download 411

411

the image again, and so that means, of course, trouble. 412

412

And so in the next lecture, 413

413

we will develop a simple algorithm, 414

414

which will basically only update the DOM in places 415

415

where we actually want to update the markup. 416

416

So only, for example, this number here, and these numbers, 417

417

and leaving everything else the same, 418

418

so without re rendering everything, 419

419

and that will be a lot of fun. 420

420

And so let's go do that next.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.