All language subtitles for 19. Implementing Bookmarks - Part 1

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

Well, welcome back. 2

2

And I hope that you're still having fun in this project. 3

3

Now, the next part of this project 4

4

is going to be implementing bookmarks. 5

5

And so that's what we will do 6

6

in this lecture and the next one. 7

7

Okay. 8

8

And let's start again with a look at our flow chart here. 9

9

And so in this video 10

10

what we will do is simply basically adding a handler 11

11

to the recipe so that then the user can bookmark the recipe 12

12

and then a that will render or update the recipe 13

13

with the bookmark button, then update it. 14

14

And for doing that there's actually a lot of stuff 15

15

that we need to implement. 16

16

So there's a lot of work for us to do, so let's get started. 17

17

And actually, before we get started 18

18

I think we should actually also see this in action. 19

19

So here in the demo version, so let's say that we are here 20

20

on this first recipe and when I click this recipe 21

21

I then want this, icon here to change right? 22

22

And so this is now bookmarked. 23

23

So when I then go to the next result 24

24

then of course this bookmark here is back to being empty. 25

25

But when I go back to that recipe that I had bookmarked, 26

26

then it is back to being filled. 27

27

And so this means 28

28

that the current recipe is indeed a bookmark. 29

29

Then in the next lecture, we will take care 30

30

of also displaying all the bookmarks up here. 31

31

All right, but that's something different. 32

32

And so for now, let's take care of the core functionality 33

33

of being able to bookmark a recipe. 34

34

Okay and finally there's one more thing 35

35

that we actually need to do before starting that. 36

36

So I discovered a small bug here. 37

37

Let's say that we searched for something. 38

38

And then we go to page two or page three, for example 39

39

and then let's say we search for something else. 40

40

So that gives us our results. 41

41

But as we go back here 42

42

notice how we are still on page number three. 43

43

And so that is a bug that we need to fix. 44

44

Now, can you figure out maybe on your own, 45

45

why does bug is happening? 46

46

So I think that this would be a nice challenge 47

47

for you to pause this video actually 48

48

right now and try to figure out why this bug is happening. 49

49

So hopefully you figured it out. 50

50

And the reason for it is that here in the model, 51

51

when we do the search so here, 52

52

when we load the search results 53

53

of course the state is set to one. 54

54

So the page is set to one here automatically. 55

55

However, as we move to another page 56

56

then this variable here gets updated right. 57

57

But then when we search for something else 58

58

we never reset this page to one right? 59

59

And so that's what we have to do right here 60

60

where we load the search results. 61

61

So after this here, we need to say state.search.page 62

62

and set it back to once. 63

63

And so now whenever we load some new search results 64

64

so basically whenever we do a new search 65

65

then the page will reset to one. 66

66

So let's try that again now. 67

67

So we are again at page three and you already see, 68

68

we have different results. 69

69

And indeed now we are at page number one. 70

70

Okay so that was a small bug that needed to be fixed. 71

71

But now let's go back to the actual topic of this video, 72

72

which is to implement bookmarking. 73

73

So bookmarks are all about data. 74

74

And so we will start by working again in the model 75

75

and we will add a new method here. 76

76

Well actually a new function 77

77

that we export that we will then use from the controller, 78

78

which is simply add a bookmark. 79

79

And so this will receive basically a recipe 80

80

and then it will set that recipe as a bookmark. 81

81

So a recipe and then in our state, 82

82

we already have an array for bookmarks 83

83

or actually we don't, but I think I had it 84

84

in the architecture diagram. 85

85

So anyway, we have an array of bookmarks, 86

86

which we start as an empty array, 87

87

but then basically adding a bookmark 88

88

simply means to push the recipe here into this array. 89

89

Okay so what I just said is this state.bookmarks.push 90

90

and then the recipe object that we just received here. 91

91

So let's add a comment here 92

92

add bookmark because besides this 93

93

we also want to mark the current recipe as being bookmarked. 94

94

So at least if the current recipe is the same recipe 95

95

as this one that we are adding here. 96

96

So mark current recipe as bookmark 97

97

because this will then allow us to actually display 98

98

this current recipe as bookmarked in the recipe view. 99

99

So we can say if recipe.id. 100

100

So the idea of the recipe that we passed in here 101

101

is equal to the ID of the current recipe. 102

102

So the one that is currently loaded in our application 103

103

which is state.recipe.id, while in this case 104

104

we want to say state.recipe.bookmarked should be true. 105

105

So basically setting a new property on this recipe object. 106

106

So for now that is the add bookmark function here. 107

107

And so now let's create a new controller. 108

108

So a controller for adding a new bookmark, 109

109

so control, add bookmark. 110

110

And so here let's not try to add a bookmark 111

111

with the current recipe. 112

112

So model.state.recipe 113

113

and then let's also immediately log that to the console 114

114

so that we can see that it is actually marked as a bookmark. 115

115

And now of course we need a way of calling this 116

116

a controller function. 117

117

So when will that happen? 118

118

Well, it should happen when we click on this button right? 119

119

So this bookmark button 120

120

and right now the icon here is actually wrong. 121

121

So let's start by fixing that here in the recipe view. 122

122

So where is that, 123

123

here. 124

124

So here it should not be fill for now, 125

125

it should simply be the empty icon like this. 126

126

All right. 127

127

Now the name of this button here is button round 128

128

but let's add a another class here. 129

129

So let's say button 130

130

bookmark, and so now we want to listen for clicks 131

131

on this element. 132

132

However, to keep this view simple 133

133

I will not select this element, so at least not directly. 134

134

And instead I will once again, do event delegation. 135

135

So here let's add another function called addHandler 136

136

and hear add bookmark. 137

137

Which has always will receive a handler function 138

138

which in this case is going to be the controller, 139

139

we just created a minute ago. 140

140

So here this.parentelement.event listener click, 141

141

and then, or a function here. 142

142

And so in fact this is really necessary 143

143

because the element that we are trying to select. 144

144

So this button with this class 145

145

of a button bookmark does actually not exist 146

146

by the time the application is loaded, right. 147

147

So basically by the time that the page starts 148

148

this element does not exist. 149

149

And so it's impossible to add an event listener 150

150

to an element that doesn't exist. 151

151

And so that is yet another great use case 152

152

for event delegation. 153

153

So we do exactly what we do here 154

154

which is to simply listen for the event on a parent element 155

155

and then try to figure out if the click actually happened 156

156

on the element that we are looking for. 157

157

And so once again, we will do a button element here 158

158

and then e.target.closest, because one more time 159

159

the user might actually click on the icon element. 160

160

So on the SVG data is in there. 161

161

Okay and if there is a button 162

162

or let's actually say, if there is no button 163

163

then return so the same guard clause as always 164

164

and otherwise call or handler. 165

165

So this was pretty straight forward I believe 166

166

because we have done this many times before. 167

167

Okay and so now 168

168

all we have to do is in the controller module 169

169

to call this method here right. 170

170

So recipe, view.addhandler add bookmark 171

171

and then we pass in control add bookmark. 172

172

And so then when we click the element that we just selected 173

173

then we will add the current recipe as a bookmark 174

174

and prologue also that current recipe to the console 175

175

so that we can see that it was actually marked 176

176

as bookmarked. 177

177

Okay so lets the reload just to make sure 178

178

let's click the button. 179

179

And did anything happen? 180

180

Oh yeah, I think it just 181

181

yeah locked this object here. 182

182

So let's see. 183

183

Ah, and here we have it. 184

184

So bookmarked is now set to true. 185

185

Great. 186

186

So an important piece of the work here is already done 187

187

but now we then want to render here this icon as filled. 188

188

And so let's go back to our view and basically say 189

189

if bookmarked is true, then a render the filled icon. 190

190

And if not, then simply render this one. 191

191

So that should be easy enough. 192

192

So not here in the view, of course 193

193

but in the recipe view where regenerate a markup. 194

194

So yeah, this is the button here, and this is the icon 195

195

that I'm talking about. 196

196

So here, when the recipe is bookmarked 197

197

we want to add like this fill part. 198

198

And so we can simply say this.data 199

199

which is the recipe.bookmarked. 200

200

So if so then here create a fill and otherwise nothing. 201

201

Okay and now finally, to actually make this work 202

202

of course, we will also have to update the entire recipe. 203

203

So recipe view and so this is why we created 204

204

that update method before. 205

205

And so now again, this method is coming in very useful 206

206

because otherwise we would have to render the entire page 207

207

or actually the entire view 208

208

which would make a lot of sense 209

209

because with this we will only update the element 210

210

which has actually changed. 211

211

And so here then again we need to pass in the data 212

212

that we want to update. 213

213

And so that's model.state.recipe once again. 214

214

Okay and so now as we click here 215

215

let's see, and indeed the button was updated. 216

216

Now we get all of these logs here. 217

217

Let's take them out that is in the view. 218

218

So that's this one here. 219

219

Great. 220

220

So here, let's now search for something. 221

221

So let's mark this one here as a bookmark, 222

222

then this one here 223

223

but now as we come back here, let's see what happens. 224

224

And you see that the bookmark is actually gone, 225

225

right? 226

226

So now here you no longer see bookmarked set to true. 227

227

So why is that? 228

228

Well, as we load each new recipe 229

229

it will always be loaded basically from scratch. 230

230

So it will be loaded from the API, right? 231

231

We are not loading this recipe from the bookmarks. 232

232

And actually we won't do that. 233

233

But what we will do is to now use the data that we store 234

234

in the bookmarks array and the state 235

235

to basically Mark any recipe that we load as bookmarked, 236

236

if it is already in the bookmarks array. 237

237

So that probably sounded more complicated 238

238

than it actually is. 239

239

Okay so let's go here back to the model 240

240

and then to our function, which loads the recipe. 241

241

So that is this one. 242

242

So here the as we got all this data 243

243

and store it in the state. 244

244

Then what we can do is to check if there is already a recipe 245

245

with the same ID in the bookmarks state. 246

246

And if it is then we will mark the current recipe 247

247

that we just loaded from the API as bookmarked set to true. 248

248

So let's use 249

249

one of the nice array methods that we learned about, 250

250

which is the sum method. 251

251

And remember that the sum method returns true or false. 252

252

And so that's great for doing an if check like this. 253

253

So here we can check if state.bookmarks.some 254

254

which basically means any, 255

255

so at least that's how I like to think about this method. 256

256

So this method will loop over an array 257

257

and then return true if any of them actually has to 258

258

for the condition that we specify here. 259

259

So if bookmark.id is the same 260

260

as the ID that we just received here 261

261

okay, let's call this here bookmark actually. 262

262

And so basically what this means is that 263

263

if there is any bookmark, which has the bookmark ID 264

264

equal to the ID that we just received 265

265

well, then we want the current recipe 266

266

which is state.recipe to be bookmarked. 267

267

So bookmark equal to true. 268

268

Okay and otherwise we wanted a set to false. 269

269

And so with this, all the recipes that we now load 270

270

we'll always have bookmarked set to either true or false. 271

271

Okay great. 272

272

And so now we actually used this state.bookmarks 273

273

for anything meaningful. 274

274

So up until this point, we had stored the recipe 275

275

in the bookmarks array, but it wasn't really useful. 276

276

So there was really no point up until now, 277

277

but now here use basically use this array 278

278

in order to store all the bookmarks 279

279

so that when we come back to one of them, 280

280

we can then mark the recipe as being bookmarked. 281

281

So let's try this now again. 282

282

So bookmarking this, then I come to this 283

283

and yeah so that worked and you see that it is bookmarked 284

284

set to true and the previous one. 285

285

So the double crust stuffed pizza 286

286

is of course bookmarked set to false. 287

287

And so when we click that here, 288

288

it doesn't have the bookmark. 289

289

Now we bookmarked it. 290

290

And when we come back to it, then there it is. 291

291

Okay and now just as the final piece here, 292

292

when we click on this button again 293

293

we then want to unbookmark basically this recipe. 294

294

So we want to remove it from the bookmarks 295

295

but right now, of course, that doesn't happen. 296

296

And so what we need now is basically yet another method 297

297

or function here in our model, 298

298

which will simply remove a bookmark. 299

299

So doing the opposite of add bookmark. 300

300

So const delete bookmark 301

301

and this one will simply receive an ID 302

302

because that is actually simpler. 303

303

And this is actually a common pattern 304

304

that you will see in programming when we add something 305

305

we get the entire data. 306

306

And when we want to delete something, we only get to the ID. 307

307

So this is a pretty common pattern again. 308

308

So what we want to do here is to basically delete the recipe 309

309

which has this ID from the bookmarks array right? 310

310

So state.bookmarks and then to delete something, 311

311

we use the splice method. 312

312

Remember, and then here we need the index 313

313

where the element is actually located 314

314

that we want to delete. 315

315

So we will calculate the index in a second. 316

316

And then how many items we want to delete 317

317

which has only one. 318

318

And so this index here, we can calculate it by using 319

319

our old friend defined index method. 320

320

So state.bookmarks. 321

321

And I think we already did something very similar to this 322

322

in the Bankist application. 323

323

So here we are looking for the element 324

324

which has the ID equal to the ID that was passed in. 325

325

So there's going to be one bookmark 326

326

for which this condition here is true. 327

327

So word current bookmark.id is equal to this ID. 328

328

And so for this element where this condition is true 329

329

the index will be returned. 330

330

And then we can take that index and deleted from the array. 331

331

And then finally, let's also mark the current recipe 332

332

as not a bookmark anymore. 333

333

So as not bookmarked and here as well, 334

334

and here let's say delete bookmark, okay. 335

335

And now we need to of course use this function somewhere. 336

336

And that's always, that can only be in the controller. 337

337

Okay, so this control add bookmark function will be executed 338

338

whenever we click on that bookmark button. 339

339

And so here we now need to control 340

340

what exactly should happen in that case. 341

341

So when do we actually want to add a bookmark? 342

342

Well, actually only when the recipe is not yet bookmarked. 343

343

So let's write that. 344

344

So if model.state.recipe.bookmarked 345

345

so if that's false, 346

346

then do this. 347

347

So add to bookmark then but if not, 348

348

and so let's now do this instead of an else 349

349

because this is more readable 350

350

then we want to delete bookmark. 351

351

And again, here we pass in actually the ID like this 352

352

and that's actually it, and this is possible. 353

353

Remember so it's possible that we read the bookmark property 354

354

right at the beginning 355

355

because we add that to all the recipes 356

356

that are ever loaded right at the beginning right here. 357

357

Okay and so now this should not work. 358

358

Let's try avocado now for a change. 359

359

So some sushi here that looks delicious 360

360

and we get ourselves a bug. 361

361

So let's go to line number eight, 98 actually. 362

362

So 98. 363

363

Oh and here we are using recipe.id 364

364

because we simply copied it from here. 365

365

So you see that simply copying some code many times can 366

366

make us run into bugs. 367

367

So here, of course we are already receiving the ID. 368

368

So that's only ID let's go back 369

369

and let's search for avocado again. 370

370

So here we have that let's bookmark it. 371

371

Well, that didn't work. 372

372

Let's see why, so probably something wrong 373

373

in our controller. 374

374

So let's lock this year to the console, 375

375

just to see if this is having any effect 376

376

let's clear this here, and it is false. 377

377

And so, 378

378

therefore this should have worked 379

379

but somehow nothing worked. 380

380

So this code here did not get executed for some reason. 381

381

Oh and actually I see what is happening. 382

382

So this code actually did get executed. 383

383

So this code here, will mark the recipe as bookmarked, 384

384

but then in the next line of code right here, 385

385

then the recipe is already bookmarked. 386

386

And so then it will delete that bookmark. 387

387

And so here, actually we need an else. 388

388

Okay so that's the kind of sometimes difficult 389

389

bugs to find, but I'm sure that with time, 390

390

you will also be able to find all of these bug. 391

391

So let's click on some recipe here, mark it as a bookmark. 392

392

Then we go here to some other one mark that. 393

393

Then here, that is still working and now let's click 394

394

and see if it disappears. 395

395

And yes, it does. 396

396

Now do the same here, come back. 397

397

And it is still unbookmarked. 398

398

Well, all right. 399

399

So with this, we have two core functionality 400

400

of bookmarking actually already implemented. 401

401

So great job once again. 402

402

And now all that is missing 403

403

is that we display all our bookmarks up here 404

404

in this bookmarks panel. 405

405

And that is a little bit more work than it might sound. 406

406

And so that's leave that for our next video.

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