1
00:00:01,300 --> 00:00:04,560
<v Jonas>Let's now start implementing the next feature</v>

2
00:00:04,560 --> 00:00:06,140
of our application,

3
00:00:06,140 --> 00:00:09,143
which is going to be the search functionality.

4
00:00:11,190 --> 00:00:15,653
And let's start by taking a look and or flowchart here.

5
00:00:16,550 --> 00:00:17,950
And so, again,

6
00:00:17,950 --> 00:00:21,960
we already have this part here basically now implemented,

7
00:00:21,960 --> 00:00:26,960
and now, we are going to work basically first on this part.

8
00:00:27,400 --> 00:00:29,330
So handling the event of a user

9
00:00:29,330 --> 00:00:32,050
searching for recipes,

10
00:00:32,050 --> 00:00:35,840
then loading the search results and rendering them.

11
00:00:35,840 --> 00:00:39,060
So that's going to be this lecture and the next one.

12
00:00:39,060 --> 00:00:40,470
And then afterwards,

13
00:00:40,470 --> 00:00:43,760
we are going to worry about the pagination.

14
00:00:43,760 --> 00:00:47,850
So again, we will now focus on these three parts.

15
00:00:47,850 --> 00:00:48,750
And so for that,

16
00:00:48,750 --> 00:00:51,840
we need to now implement the model, the view

17
00:00:51,840 --> 00:00:55,340
and the controller that binds everything together.

18
00:00:55,340 --> 00:00:59,450
And usually, I find it easiest to start with the data.

19
00:00:59,450 --> 00:01:01,490
So basically with the model,

20
00:01:01,490 --> 00:01:03,190
which means in this case,

21
00:01:03,190 --> 00:01:06,340
starting to make some API calls

22
00:01:06,340 --> 00:01:08,920
in order to load some search results.

23
00:01:08,920 --> 00:01:11,420
And then, once we have that part working,

24
00:01:11,420 --> 00:01:13,810
we can then render them on the screen

25
00:01:13,810 --> 00:01:16,643
and also care about the actual event.

26
00:01:18,370 --> 00:01:22,250
Okay, so let's actually leave that open here at the end

27
00:01:22,250 --> 00:01:24,690
and go to our model here,

28
00:01:24,690 --> 00:01:28,760
and start implementing the search functionality.

29
00:01:28,760 --> 00:01:30,860
So, just like before,

30
00:01:30,860 --> 00:01:32,990
we are going to create a function

31
00:01:32,990 --> 00:01:34,670
that will be exported

32
00:01:34,670 --> 00:01:35,840
so that it can be used

33
00:01:35,840 --> 00:01:37,420
by the controller.

34
00:01:37,420 --> 00:01:38,610
And this one,

35
00:01:38,610 --> 00:01:40,410
I'm gonna call it loadSearchResults.

36
00:01:44,730 --> 00:01:49,490
And so, since this one will be performing AJAX calls

37
00:01:49,490 --> 00:01:51,823
it's going to be an async function.

38
00:01:52,980 --> 00:01:54,850
Now, again dysfunction here

39
00:01:54,850 --> 00:01:57,660
is going to be called by the controller.

40
00:01:57,660 --> 00:01:59,730
And so, it's going to be the controller

41
00:01:59,730 --> 00:02:01,160
who will tell this function

42
00:02:01,160 --> 00:02:03,440
what it would actually search for.

43
00:02:03,440 --> 00:02:05,870
So basically, it will pass in a query

44
00:02:07,180 --> 00:02:09,340
like string, which we can then

45
00:02:09,340 --> 00:02:14,340
pluck into our API call, now, right?

46
00:02:14,350 --> 00:02:18,293
And here we are going to need a try catch block,

47
00:02:21,750 --> 00:02:23,360
and here in the catch block,

48
00:02:23,360 --> 00:02:24,963
all we will do is to,

49
00:02:26,540 --> 00:02:28,040
basically do the same as here.

50
00:02:30,490 --> 00:02:32,860
So, all we're really interested in here

51
00:02:32,860 --> 00:02:35,080
is to throw the error again

52
00:02:35,080 --> 00:02:36,690
so that eventually,

53
00:02:36,690 --> 00:02:39,520
we will be able to use it in the controller.

54
00:02:39,520 --> 00:02:41,080
So just like before

55
00:02:41,080 --> 00:02:42,360
in the last lecture,

56
00:02:42,360 --> 00:02:45,083
where we threw with the error here again.

57
00:02:45,920 --> 00:02:48,400
So that part is easy,

58
00:02:48,400 --> 00:02:51,520
but now let's actually implement the functionality.

59
00:02:51,520 --> 00:02:52,510
And to do that,

60
00:02:52,510 --> 00:02:55,833
let's go back to our documentations page.

61
00:02:57,350 --> 00:03:01,490
And so, this is how we get all recipes.

62
00:03:01,490 --> 00:03:05,860
So making a get request to this path,

63
00:03:05,860 --> 00:03:08,660
and then, with the search parameter,

64
00:03:08,660 --> 00:03:10,820
and the way we add a parameter,

65
00:03:10,820 --> 00:03:13,560
and I think I explained this before

66
00:03:13,560 --> 00:03:15,710
is with the question mark,

67
00:03:15,710 --> 00:03:17,930
and then search equal,

68
00:03:17,930 --> 00:03:20,020
and then, pizza here in our case

69
00:03:20,020 --> 00:03:21,973
is actually the search query.

70
00:03:22,920 --> 00:03:23,810
And again, for now,

71
00:03:23,810 --> 00:03:26,020
don't worry about the key.

72
00:03:26,020 --> 00:03:28,120
And we can actually already see

73
00:03:28,120 --> 00:03:31,830
what the results will look like here for pizza.

74
00:03:31,830 --> 00:03:33,280
And so, basically,

75
00:03:33,280 --> 00:03:34,113
this is the URL

76
00:03:34,113 --> 00:03:38,660
that we need to call in our AJAX request.

77
00:03:38,660 --> 00:03:40,060
So let me actually copy it

78
00:03:41,530 --> 00:03:43,280
and let's go back.

79
00:03:43,280 --> 00:03:44,113
And so now,

80
00:03:44,113 --> 00:03:46,210
we can, just like before,

81
00:03:46,210 --> 00:03:48,363
use the get JSON method.

82
00:03:49,270 --> 00:03:51,420
And so, that will then fetch the data

83
00:03:51,420 --> 00:03:53,640
and also convert it to JSON

84
00:03:53,640 --> 00:03:56,663
and create an error if something went wrong.

85
00:03:58,320 --> 00:04:00,500
So get JSON returns a promise.

86
00:04:00,500 --> 00:04:02,370
And so we await that here

87
00:04:02,370 --> 00:04:04,210
and store it into data,

88
00:04:04,210 --> 00:04:06,320
just like always.

89
00:04:06,320 --> 00:04:07,670
So get JSON

90
00:04:07,670 --> 00:04:09,313
and then the URL,

91
00:04:10,330 --> 00:04:12,910
and we need a template literal.

92
00:04:12,910 --> 00:04:17,910
And so, yeah now we just have to replace everything

93
00:04:18,280 --> 00:04:19,980
to make this work.

94
00:04:19,980 --> 00:04:20,930
And the first thing

95
00:04:20,930 --> 00:04:23,810
is to actually take this here again out,

96
00:04:23,810 --> 00:04:26,496
and replace it with this API URL

97
00:04:26,496 --> 00:04:31,413
that we already have in our configuration file, right?

98
00:04:34,470 --> 00:04:36,593
So API URL,

99
00:04:37,740 --> 00:04:39,560
and I think

100
00:04:39,560 --> 00:04:42,133
that actually already includes the recipes.

101
00:04:44,640 --> 00:04:46,790
Yup, so it's everything.

102
00:04:46,790 --> 00:04:51,520
And usually, actually a URL ends with a slash,

103
00:04:51,520 --> 00:04:53,710
so it should be like this.

104
00:04:53,710 --> 00:04:56,080
And so here, let's take that out,

105
00:04:56,080 --> 00:04:58,403
actually, and then here as well.

106
00:04:59,810 --> 00:05:02,120
Then here, question mark search

107
00:05:02,120 --> 00:05:04,270
and then this one is going to be our query.

108
00:05:06,950 --> 00:05:08,340
Now, right?

109
00:05:08,340 --> 00:05:11,080
And so, we can then

110
00:05:11,080 --> 00:05:12,840
already log that data

111
00:05:12,840 --> 00:05:13,990
to the console,

112
00:05:13,990 --> 00:05:15,380
to take a look at it

113
00:05:15,380 --> 00:05:18,230
before we then manipulate it a little bit.

114
00:05:18,230 --> 00:05:19,290
And so right now,

115
00:05:19,290 --> 00:05:21,710
this would already be working.

116
00:05:21,710 --> 00:05:22,730
And so let's,

117
00:05:22,730 --> 00:05:26,200
before we actually write any controller or any view,

118
00:05:26,200 --> 00:05:29,490
or we can already call that function here.

119
00:05:29,490 --> 00:05:31,153
So load search results,

120
00:05:32,380 --> 00:05:33,790
and then let's try it,

121
00:05:33,790 --> 00:05:36,280
has always with pizza

122
00:05:36,280 --> 00:05:37,573
and see what we get.

123
00:05:40,350 --> 00:05:41,803
So that's right here.

124
00:05:42,820 --> 00:05:47,230
And indeed, this is the result that we get here.

125
00:05:47,230 --> 00:05:49,613
So it's coming from model at line 35.

126
00:05:50,480 --> 00:05:52,600
So that's where we were.

127
00:05:52,600 --> 00:05:53,433
And so here,

128
00:05:53,433 --> 00:05:55,720
is the data that we get back.

129
00:05:55,720 --> 00:05:57,370
So we have an object

130
00:05:57,370 --> 00:05:59,510
which has a data property,

131
00:05:59,510 --> 00:06:02,010
which then has a recipe's property,

132
00:06:02,010 --> 00:06:03,523
which is this array.

133
00:06:05,550 --> 00:06:08,070
And then, each array contains

134
00:06:08,070 --> 00:06:09,470
all of this data

135
00:06:09,470 --> 00:06:12,033
about each of the recipes.

136
00:06:13,220 --> 00:06:17,060
So, again, this object here is called data

137
00:06:17,060 --> 00:06:19,120
then in there, there is data again,

138
00:06:19,120 --> 00:06:21,390
and then in there, there is recipes,

139
00:06:21,390 --> 00:06:22,807
which is then,

140
00:06:22,807 --> 00:06:24,350
the array itself

141
00:06:24,350 --> 00:06:25,640
where each of the elements

142
00:06:25,640 --> 00:06:26,720
is an object

143
00:06:26,720 --> 00:06:28,910
with only some of the data

144
00:06:28,910 --> 00:06:30,900
about the recipe.

145
00:06:30,900 --> 00:06:33,840
So you see, it's not the complete recipe object,

146
00:06:33,840 --> 00:06:35,690
it's only some of the data

147
00:06:35,690 --> 00:06:38,160
so that we can actually display it

148
00:06:38,160 --> 00:06:40,070
then here in the search results.

149
00:06:40,070 --> 00:06:42,290
So without the unnecessary data

150
00:06:42,290 --> 00:06:45,140
like ingredients and all that.

151
00:06:45,140 --> 00:06:47,900
All right, so let's now take this data

152
00:06:47,900 --> 00:06:50,840
and store it into our state.

153
00:06:50,840 --> 00:06:53,330
And also, we will want to change,

154
00:06:53,330 --> 00:06:54,930
again, this one here,

155
00:06:54,930 --> 00:06:56,800
so to image only.

156
00:06:56,800 --> 00:07:00,240
And so, we will basically create some new objects

157
00:07:00,240 --> 00:07:02,683
based on this data that we receive here.

158
00:07:05,090 --> 00:07:06,650
All right.

159
00:07:06,650 --> 00:07:11,650
So, we get data.data.recipes.

160
00:07:13,970 --> 00:07:15,490
So this is the array.

161
00:07:15,490 --> 00:07:18,070
So this is the array of all the objects.

162
00:07:18,070 --> 00:07:20,170
And now we want to create a new array

163
00:07:20,170 --> 00:07:22,110
which contains the new objects

164
00:07:22,110 --> 00:07:24,093
where the property names are different.

165
00:07:25,430 --> 00:07:27,223
So, let's map over this,

166
00:07:29,210 --> 00:07:30,380
and each element

167
00:07:30,380 --> 00:07:32,163
is going to be a recipe.

168
00:07:35,070 --> 00:07:38,840
And then here, we will simply return a new object.

169
00:07:38,840 --> 00:07:41,850
That's actually copied a code from here

170
00:07:41,850 --> 00:07:45,270
because they are the same,

171
00:07:45,270 --> 00:07:46,370
at least some of them.

172
00:07:47,970 --> 00:07:49,593
So taking all this,

173
00:07:50,600 --> 00:07:53,133
int here now, this is only called a rec.

174
00:07:55,630 --> 00:07:59,437
Okay, and also we don't have the source URL,

175
00:08:00,560 --> 00:08:05,183
we only have ID, title, publisher and image URL, okay.

176
00:08:07,160 --> 00:08:10,880
So this will return a new array with the new objects.

177
00:08:10,880 --> 00:08:11,713
And so now,

178
00:08:11,713 --> 00:08:13,293
where should we store that?

179
00:08:14,140 --> 00:08:15,870
Well, as you can guess,

180
00:08:15,870 --> 00:08:18,780
we will put it also in our state.

181
00:08:18,780 --> 00:08:21,950
So again, the state contains all the data that we need

182
00:08:21,950 --> 00:08:24,770
in order to build our application.

183
00:08:24,770 --> 00:08:26,430
So let's call this one search

184
00:08:27,620 --> 00:08:28,560
and all the data

185
00:08:28,560 --> 00:08:29,940
about the application

186
00:08:29,940 --> 00:08:31,360
that I just mentioned

187
00:08:31,360 --> 00:08:32,400
might as well

188
00:08:32,400 --> 00:08:35,203
also include the search query itself.

189
00:08:36,420 --> 00:08:38,380
So let's create a new object here

190
00:08:38,380 --> 00:08:40,803
and then specify the query,

191
00:08:41,930 --> 00:08:43,993
which we start as an empty string.

192
00:08:44,830 --> 00:08:48,040
And then, the results, let's say,

193
00:08:48,040 --> 00:08:49,880
results, and will start

194
00:08:49,880 --> 00:08:51,313
as an empty array.

195
00:08:52,620 --> 00:08:54,300
So, basically the state

196
00:08:54,300 --> 00:08:56,390
should contain all the data

197
00:08:56,390 --> 00:08:58,600
really about the application.

198
00:08:58,600 --> 00:08:59,600
Now, in this case,

199
00:08:59,600 --> 00:09:03,070
we might not even need the query for now,

200
00:09:03,070 --> 00:09:04,500
but it's still a good idea

201
00:09:04,500 --> 00:09:07,420
to already store it here in the state,

202
00:09:07,420 --> 00:09:08,660
because maybe one day

203
00:09:08,660 --> 00:09:09,910
we will need it.

204
00:09:09,910 --> 00:09:12,900
And then the data's already there for us.

205
00:09:12,900 --> 00:09:16,110
For example, we might want to add some analytics

206
00:09:16,110 --> 00:09:17,230
in the future

207
00:09:17,230 --> 00:09:20,340
to know which queries are made the most.

208
00:09:20,340 --> 00:09:21,680
And so by then,

209
00:09:21,680 --> 00:09:23,120
yeah, as I said,

210
00:09:23,120 --> 00:09:25,113
that would become useful.

211
00:09:26,920 --> 00:09:27,753
Okay.

212
00:09:28,640 --> 00:09:31,060
But anyway, let's now store this data

213
00:09:31,060 --> 00:09:36,060
in state.search.results, right.

214
00:09:41,000 --> 00:09:42,030
And here at the beginning,

215
00:09:42,030 --> 00:09:43,800
the very first thing

216
00:09:43,800 --> 00:09:45,060
that we're going to do

217
00:09:45,060 --> 00:09:48,980
is to state.search.query

218
00:09:52,350 --> 00:09:53,513
equal to query.

219
00:09:55,860 --> 00:09:56,693
All right.

220
00:09:58,190 --> 00:09:59,950
And now, let's quickly

221
00:09:59,950 --> 00:10:01,800
just to see if everything worked,

222
00:10:01,800 --> 00:10:03,453
log data to the console.

223
00:10:05,080 --> 00:10:09,893
So state.search.results.

224
00:10:11,406 --> 00:10:12,923
And here we are.

225
00:10:14,060 --> 00:10:18,830
So that is exactly the kind of array that we had before.

226
00:10:18,830 --> 00:10:20,960
And now the image URL we had before

227
00:10:20,960 --> 00:10:22,630
is indeed called image.

228
00:10:22,630 --> 00:10:25,593
And so everything has the same format as before.

229
00:10:26,640 --> 00:10:28,090
So, we needed to do that

230
00:10:28,090 --> 00:10:31,430
because here the image is also called image.

231
00:10:31,430 --> 00:10:34,690
And of course, we want everything to have the same names

232
00:10:34,690 --> 00:10:38,053
throughout the entire application, all right.

233
00:10:38,910 --> 00:10:40,480
So let's get rid of this

234
00:10:40,480 --> 00:10:41,340
because of course,

235
00:10:41,340 --> 00:10:44,810
we want to call this function in a controller.

236
00:10:44,810 --> 00:10:46,400
And so let's go there

237
00:10:46,400 --> 00:10:47,440
to the controller

238
00:10:48,550 --> 00:10:51,620
and basically create a new function

239
00:10:51,620 --> 00:10:54,023
which is going to be like the new controller.

240
00:10:55,060 --> 00:10:57,513
So const controlSearchResults.

241
00:11:01,000 --> 00:11:01,833
And so this one

242
00:11:01,833 --> 00:11:05,460
we'll call the asynchronous function loadSearchResults.

243
00:11:05,460 --> 00:11:06,900
And so this one, of course

244
00:11:06,900 --> 00:11:11,743
then also need to be an asynchronous function itself.

245
00:11:13,824 --> 00:11:16,213
And so, as always try catch,

246
00:11:21,050 --> 00:11:24,030
and here for now, let's simply log the error

247
00:11:24,030 --> 00:11:25,630
and we will then fix that later.

248
00:11:26,700 --> 00:11:29,010
So, here is where we actually

249
00:11:29,010 --> 00:11:33,930
will want to call the loadSearchResults that we just built.

250
00:11:33,930 --> 00:11:36,933
So that is in model.loadSearchResults.

251
00:11:39,710 --> 00:11:40,720
And here we then,

252
00:11:40,720 --> 00:11:42,700
we'll need to pass in the query,

253
00:11:42,700 --> 00:11:46,420
but for now, let's just do that again manually.

254
00:11:46,420 --> 00:11:47,253
And of course,

255
00:11:47,253 --> 00:11:49,400
we need to await this,

256
00:11:49,400 --> 00:11:52,530
but we do not store any results anywhere

257
00:11:52,530 --> 00:11:56,260
because, just like the loadRecipe function,

258
00:11:56,260 --> 00:11:59,860
this one also doesn't return anything.

259
00:11:59,860 --> 00:12:00,780
All it does

260
00:12:00,780 --> 00:12:02,533
is to manipulate the state.

261
00:12:03,402 --> 00:12:06,600
And so, then we should be able to do this console.log

262
00:12:07,680 --> 00:12:08,740
in the controller

263
00:12:08,740 --> 00:12:12,173
and still get access to the results, right?

264
00:12:14,070 --> 00:12:16,090
So, let's see.

265
00:12:16,090 --> 00:12:19,560
Now, of course, we first have to also call this function.

266
00:12:19,560 --> 00:12:20,780
And again, later,

267
00:12:20,780 --> 00:12:23,727
we will, of course hook this us up to an event list

268
00:12:23,727 --> 00:12:25,880
and our material, let's just

269
00:12:27,050 --> 00:12:29,213
call it right away.

270
00:12:32,120 --> 00:12:36,733
And now we get status not defined, all right.

271
00:12:37,700 --> 00:12:39,060
And that is because,

272
00:12:39,060 --> 00:12:44,060
of course it needs to be model.state.search.results.

273
00:12:45,740 --> 00:12:49,620
So you see that this is becoming a pretty long chain here

274
00:12:49,620 --> 00:12:52,730
but nevermind, that's not a problem at all,

275
00:12:52,730 --> 00:12:55,423
because we know exactly what all of this is.

276
00:12:56,610 --> 00:12:57,950
And so, now indeed

277
00:12:57,950 --> 00:13:02,900
we get back our 59 search results for pizza.

278
00:13:02,900 --> 00:13:06,010
But now, instead of only searching for pizza,

279
00:13:06,010 --> 00:13:08,970
we actually want to get the query right here

280
00:13:08,970 --> 00:13:11,880
from this input field, right?

281
00:13:11,880 --> 00:13:14,350
And we also want to start this whole process

282
00:13:14,350 --> 00:13:16,573
of loading the search results.

283
00:13:17,450 --> 00:13:18,870
So we only want that to happen

284
00:13:18,870 --> 00:13:21,680
when this button here is clicked.

285
00:13:21,680 --> 00:13:24,950
And so, now let's basically create a view

286
00:13:24,950 --> 00:13:27,570
only for this search part here.

287
00:13:27,570 --> 00:13:28,840
So right here,

288
00:13:28,840 --> 00:13:30,400
we will have a view

289
00:13:30,400 --> 00:13:31,800
for this year.

290
00:13:31,800 --> 00:13:33,080
So for the search field,

291
00:13:33,080 --> 00:13:34,300
and for the button,

292
00:13:34,300 --> 00:13:36,140
and then a different view

293
00:13:36,140 --> 00:13:39,460
which will actually render the results.

294
00:13:39,460 --> 00:13:40,850
So, it's a good idea

295
00:13:40,850 --> 00:13:43,630
to keep every view really focused.

296
00:13:43,630 --> 00:13:44,840
And so, it's best

297
00:13:44,840 --> 00:13:47,180
to just do one for this part,

298
00:13:47,180 --> 00:13:49,580
and then one for displaying the results,

299
00:13:49,580 --> 00:13:52,000
also because in the user interface,

300
00:13:52,000 --> 00:13:55,260
they're actually in kind of different places also.

301
00:13:55,260 --> 00:13:58,030
So it makes sense to have a different view.

302
00:13:58,030 --> 00:13:59,280
Now this view here

303
00:13:59,280 --> 00:14:00,120
is of course

304
00:14:00,120 --> 00:14:02,120
not going to render anything,

305
00:14:02,120 --> 00:14:03,740
but what it will do

306
00:14:03,740 --> 00:14:06,020
is to basically give us the content

307
00:14:06,020 --> 00:14:07,963
of this input field.

308
00:14:08,820 --> 00:14:10,690
So getting that input data

309
00:14:10,690 --> 00:14:11,523
is of course

310
00:14:11,523 --> 00:14:13,830
something that has to do with a DOM.

311
00:14:13,830 --> 00:14:15,400
And so, it should be in a view

312
00:14:15,400 --> 00:14:18,750
and not in a controller, right?

313
00:14:18,750 --> 00:14:19,890
So of course,

314
00:14:19,890 --> 00:14:21,380
if we wanted to be lazy,

315
00:14:21,380 --> 00:14:22,680
we could go ahead

316
00:14:22,680 --> 00:14:24,833
and select the element that we want.

317
00:14:25,810 --> 00:14:26,880
So it doesn't matter.

318
00:14:26,880 --> 00:14:28,240
And then from there,

319
00:14:28,240 --> 00:14:30,630
we would simply get the value

320
00:14:30,630 --> 00:14:33,113
and then use that as our query.

321
00:14:34,600 --> 00:14:36,680
So again, we could do that here,

322
00:14:36,680 --> 00:14:39,180
but this is clearly about the DOM.

323
00:14:39,180 --> 00:14:41,820
And so, in order to follow our architecture,

324
00:14:41,820 --> 00:14:44,810
we will create a new view right now.

325
00:14:44,810 --> 00:14:49,810
And this one is going to be called the searchView.js.

326
00:14:52,750 --> 00:14:54,610
And just like before,

327
00:14:54,610 --> 00:14:59,610
here, we will create a class called searchView

328
00:15:03,070 --> 00:15:05,870
and we will then not export that class

329
00:15:05,870 --> 00:15:07,520
but export an instance,

330
00:15:07,520 --> 00:15:10,573
so an object that was created by this class.

331
00:15:11,670 --> 00:15:14,770
So export default new SearchView,

332
00:15:15,950 --> 00:15:18,023
and without passing in any data,

333
00:15:19,130 --> 00:15:20,540
done just like before,

334
00:15:20,540 --> 00:15:22,593
we will have a parent element.

335
00:15:24,270 --> 00:15:26,673
So just like in the recipe view,

336
00:15:27,640 --> 00:15:28,933
so a parent element,

337
00:15:30,150 --> 00:15:32,403
and then we will set that to something,

338
00:15:35,030 --> 00:15:38,960
query selector, and now let's see what we get

339
00:15:38,960 --> 00:15:40,990
here in the DOM.

340
00:15:40,990 --> 00:15:42,293
So in the HTML,

341
00:15:43,270 --> 00:15:44,703
so the search,

342
00:15:46,940 --> 00:15:48,350
now, it's this one.

343
00:15:48,350 --> 00:15:50,730
So we have this entire form,

344
00:15:50,730 --> 00:15:52,790
which is called search

345
00:15:52,790 --> 00:15:55,050
and which has this input field here

346
00:15:55,050 --> 00:15:57,070
and also the button.

347
00:15:57,070 --> 00:15:59,700
And so I think that this is the element

348
00:15:59,700 --> 00:16:02,010
that makes sense to select.

349
00:16:02,010 --> 00:16:07,010
So the one with the class of search, so .search.

350
00:16:09,150 --> 00:16:12,500
So this is our parent element here in this case.

351
00:16:12,500 --> 00:16:17,080
Now, again, this class is not going to render anything.

352
00:16:17,080 --> 00:16:19,820
All we want is to get the query

353
00:16:19,820 --> 00:16:22,860
and eventually to also listen for the click event

354
00:16:22,860 --> 00:16:24,340
on the button,

355
00:16:24,340 --> 00:16:26,720
but let's start with the query here.

356
00:16:26,720 --> 00:16:28,540
And so, let's create a method

357
00:16:28,540 --> 00:16:32,973
that we will then call from the controller called getQuery.

358
00:16:35,490 --> 00:16:36,450
And all this will do

359
00:16:36,450 --> 00:16:40,713
is to return this.#parentElement.

360
00:16:42,690 --> 00:16:43,523
And so again,

361
00:16:43,523 --> 00:16:47,300
that's going to be the search.

362
00:16:47,300 --> 00:16:48,270
And then from there,

363
00:16:48,270 --> 00:16:51,713
we want to select this input field.

364
00:16:53,930 --> 00:16:56,220
So this one with this class.

365
00:16:56,220 --> 00:16:59,470
And so let's a select this child element

366
00:16:59,470 --> 00:17:01,533
using a querySelector,

367
00:17:06,410 --> 00:17:09,913
and then simply get the value of that.

368
00:17:11,209 --> 00:17:14,193
Okay, and that's actually it.

369
00:17:15,330 --> 00:17:16,380
And again, of course

370
00:17:16,380 --> 00:17:19,090
we could have written this exact same code

371
00:17:19,090 --> 00:17:20,320
in a controller,

372
00:17:20,320 --> 00:17:22,560
but that wouldn't make any sense,

373
00:17:22,560 --> 00:17:26,040
because this is not concerned about the DOM at all.

374
00:17:26,040 --> 00:17:29,240
So we don't want to have any DOM elements in here.

375
00:17:29,240 --> 00:17:32,550
We don't even want to know what the DOM looks like.

376
00:17:32,550 --> 00:17:34,730
So actually here we have this,

377
00:17:34,730 --> 00:17:36,130
but we don't want this here.

378
00:17:37,790 --> 00:17:40,393
Let's get rid of all this clutter here actually.

379
00:17:41,890 --> 00:17:44,930
And now, I want to

380
00:17:46,800 --> 00:17:51,203
get the searchView here.

381
00:17:53,610 --> 00:17:54,753
And then here,

382
00:17:56,920 --> 00:17:58,570
we can get that query

383
00:17:59,930 --> 00:18:02,600
by saying searchView.getQuery.

384
00:18:06,110 --> 00:18:06,943
And of course,

385
00:18:06,943 --> 00:18:08,500
there might be no query.

386
00:18:08,500 --> 00:18:11,470
And so, let's add another guard clause here.

387
00:18:11,470 --> 00:18:13,073
So if there is no query,

388
00:18:14,360 --> 00:18:17,050
then return immediately.

389
00:18:17,050 --> 00:18:17,883
And so here,

390
00:18:17,883 --> 00:18:21,620
we will now no longer look for pizza,

391
00:18:21,620 --> 00:18:22,663
but for query.

392
00:18:23,690 --> 00:18:24,710
Now, if we run this,

393
00:18:24,710 --> 00:18:27,430
then of course there will be no result

394
00:18:27,430 --> 00:18:30,200
because, well, right now,

395
00:18:30,200 --> 00:18:32,223
there is nothing here to be found.

396
00:18:33,290 --> 00:18:34,780
So that controller function

397
00:18:34,780 --> 00:18:36,610
runs right in the beginning

398
00:18:36,610 --> 00:18:38,830
when the application actually loads.

399
00:18:38,830 --> 00:18:40,270
And so by then of course,

400
00:18:40,270 --> 00:18:43,150
there is a no value here.

401
00:18:43,150 --> 00:18:45,660
And so, in order to actually make this work,

402
00:18:45,660 --> 00:18:48,040
we now need to listen for the event

403
00:18:48,040 --> 00:18:53,040
of basically clicking this button or submitting this form.

404
00:18:53,190 --> 00:18:55,350
And then, only on that event,

405
00:18:55,350 --> 00:18:57,300
we want to actually call,

406
00:18:57,300 --> 00:18:59,200
this controller function here.

407
00:18:59,200 --> 00:19:01,723
So not in the beginning when the script loads.

408
00:19:02,610 --> 00:19:04,600
So, in order to do that,

409
00:19:04,600 --> 00:19:05,930
we will once again,

410
00:19:05,930 --> 00:19:08,950
use the publisher subscriber pattern.

411
00:19:08,950 --> 00:19:13,950
So basically exactly what we did here, right?

412
00:19:14,580 --> 00:19:16,640
So we will list in for the event

413
00:19:16,640 --> 00:19:19,450
in the view right here,

414
00:19:19,450 --> 00:19:21,810
and then pass the controller function.

415
00:19:21,810 --> 00:19:23,260
So the handler function

416
00:19:24,170 --> 00:19:26,593
into the method that we will build here.

417
00:19:28,440 --> 00:19:32,400
So this addHandler, a search method here

418
00:19:32,400 --> 00:19:33,560
is basically going

419
00:19:33,560 --> 00:19:37,770
to be the publisher anti-control search results function

420
00:19:37,770 --> 00:19:39,893
is going to be the subscriber.

421
00:19:41,690 --> 00:19:46,160
Okay, so hopefully you really understood that pattern

422
00:19:46,160 --> 00:19:48,170
that we used before.

423
00:19:48,170 --> 00:19:49,003
And so this now,

424
00:19:49,003 --> 00:19:50,223
it should be obvious.

425
00:19:51,310 --> 00:19:54,160
So, let's take our parent element.

426
00:19:54,160 --> 00:19:57,050
So this.#parentElement of course,

427
00:19:57,050 --> 00:19:58,030
and then this is where

428
00:19:58,030 --> 00:20:00,830
we will actually add the event listener.

429
00:20:00,830 --> 00:20:02,680
So not to the button,

430
00:20:02,680 --> 00:20:04,750
but really to the entire form

431
00:20:04,750 --> 00:20:08,670
because there, we can listen for the submit event.

432
00:20:08,670 --> 00:20:10,460
And so then, this will work

433
00:20:10,460 --> 00:20:13,320
no matter if the user clicks the submit button

434
00:20:13,320 --> 00:20:17,303
or if the user hits Enter while typing the query.

435
00:20:18,640 --> 00:20:22,200
Now here, we cannot simply call the handler immediately,

436
00:20:22,200 --> 00:20:25,810
because remember, as we did many times before

437
00:20:25,810 --> 00:20:27,350
when we submit a form,

438
00:20:27,350 --> 00:20:30,680
we need to first prevent the default action,

439
00:20:30,680 --> 00:20:33,353
because otherwise the page is going to reload.

440
00:20:35,010 --> 00:20:36,897
So, preventDefault.

441
00:20:39,890 --> 00:20:41,830
And only after that,

442
00:20:41,830 --> 00:20:44,770
we can call the handler function.

443
00:20:44,770 --> 00:20:46,770
And, as you already know,

444
00:20:46,770 --> 00:20:48,290
this handler function

445
00:20:48,290 --> 00:20:51,550
should be the control searchResults function.

446
00:20:51,550 --> 00:20:52,940
And so, all we have to do now

447
00:20:52,940 --> 00:20:54,900
is to call this method

448
00:20:54,900 --> 00:20:57,293
and pass in that function.

449
00:20:58,590 --> 00:21:00,890
So, let's do that here right at the beginning.

450
00:21:01,890 --> 00:21:03,123
So searchView.addHandlerSearch.

451
00:21:07,040 --> 00:21:09,660
So you'll see that I'm always going to use

452
00:21:09,660 --> 00:21:11,590
this name here of addHandler,

453
00:21:13,840 --> 00:21:16,740
and then we pass in the controller function

454
00:21:17,740 --> 00:21:19,430
and that's it.

455
00:21:19,430 --> 00:21:21,833
So now it should actually already work.

456
00:21:23,460 --> 00:21:24,780
So let's see.

457
00:21:24,780 --> 00:21:27,680
And actually, let's clear up all this clutter

458
00:21:27,680 --> 00:21:28,623
here a little bit.

459
00:21:29,550 --> 00:21:32,270
Okay, so this console.log,

460
00:21:32,270 --> 00:21:35,413
and there's also some here in the recipe view.

461
00:21:36,380 --> 00:21:37,423
So that's this one.

462
00:21:40,470 --> 00:21:43,400
Okay, so that's again, try pizza

463
00:21:44,470 --> 00:21:48,033
and yeah, beautiful, it worked.

464
00:21:49,240 --> 00:21:50,930
So we get

465
00:21:50,930 --> 00:21:53,890
this data first here coming from the model,

466
00:21:53,890 --> 00:21:55,630
and then also in a controller,

467
00:21:55,630 --> 00:21:57,140
we also logged it.

468
00:21:57,140 --> 00:22:01,290
And so here we have the exact same 59 data

469
00:22:01,290 --> 00:22:02,293
that we had before.

470
00:22:03,130 --> 00:22:05,060
Let's try something else now,

471
00:22:05,060 --> 00:22:06,403
avocado, let's say,

472
00:22:08,020 --> 00:22:09,343
so I hit Enter,

473
00:22:10,910 --> 00:22:15,320
and, so this time we got 39 search results

474
00:22:16,650 --> 00:22:17,483
and you see,

475
00:22:17,483 --> 00:22:20,250
all of them basically have avocado

476
00:22:20,250 --> 00:22:22,400
right there in the title,

477
00:22:22,400 --> 00:22:23,650
it's really beautiful

478
00:22:23,650 --> 00:22:25,833
that it already works this great.

479
00:22:26,670 --> 00:22:28,800
Now just one small detail,

480
00:22:28,800 --> 00:22:30,460
is that, after we search,

481
00:22:30,460 --> 00:22:33,450
we should probably clear out this field.

482
00:22:33,450 --> 00:22:36,873
So let's add another small method for that in the view.

483
00:22:37,960 --> 00:22:40,053
So, and this one here,

484
00:22:42,030 --> 00:22:42,933
so clearInput,

485
00:22:44,900 --> 00:22:46,590
and once again,

486
00:22:46,590 --> 00:22:51,420
having it nicely encapsulated inside of the searchView.

487
00:22:51,420 --> 00:22:54,850
So again, this could simply be also in a controller,

488
00:22:54,850 --> 00:22:57,700
because, it's really just one line of code,

489
00:22:57,700 --> 00:23:00,750
but we want to keep everything separated.

490
00:23:00,750 --> 00:23:03,510
This will make it so much easier to add features

491
00:23:03,510 --> 00:23:05,110
in the future.

492
00:23:05,110 --> 00:23:06,660
And it's really so much better.

493
00:23:08,060 --> 00:23:12,663
So, all we do is to set this to empty and that's it.

494
00:23:14,050 --> 00:23:16,950
All right, let's try it one more time.

495
00:23:16,950 --> 00:23:18,543
Let's say pasta this time.

496
00:23:19,860 --> 00:23:24,860
Ah, of course we never called DOM method here anywhere.

497
00:23:25,090 --> 00:23:27,383
So we need to do that in the controller.

498
00:23:28,760 --> 00:23:31,603
And let's actually add some more comments here.

499
00:23:34,100 --> 00:23:35,943
So Get search query.

500
00:23:38,290 --> 00:23:42,950
And the code itself is actually pretty self explanatory.

501
00:23:42,950 --> 00:23:45,010
And so many developers will tell you

502
00:23:45,010 --> 00:23:46,760
you should not comment it,

503
00:23:46,760 --> 00:23:47,593
but I think

504
00:23:47,593 --> 00:23:50,740
that this is actually very helpful when you read the code

505
00:23:50,740 --> 00:23:53,003
in like one or two years from now.

506
00:23:54,960 --> 00:23:59,960
So, I would advise you to always write comments like this

507
00:24:00,120 --> 00:24:03,110
even if your code seems pretty obvious,

508
00:24:03,110 --> 00:24:04,540
especially when it's like

509
00:24:04,540 --> 00:24:07,103
a bigger list of instructions like this,

510
00:24:08,770 --> 00:24:11,870
so Render results.

511
00:24:11,870 --> 00:24:15,483
So right now our rendering is only a console.log.

512
00:24:16,520 --> 00:24:19,150
But here, when we get a search query,

513
00:24:19,150 --> 00:24:20,580
we can actually then

514
00:24:20,580 --> 00:24:24,030
immediately also clear it afterwards.

515
00:24:24,030 --> 00:24:25,880
Or in fact,

516
00:24:25,880 --> 00:24:28,860
in order to keep this controller even simpler,

517
00:24:28,860 --> 00:24:29,780
we can do that

518
00:24:29,780 --> 00:24:32,340
right in the getQuery method.

519
00:24:32,340 --> 00:24:35,690
So, let's go back here,

520
00:24:35,690 --> 00:24:37,720
and now we can make this private,

521
00:24:37,720 --> 00:24:40,223
so we're not going to use it outside.

522
00:24:41,170 --> 00:24:43,640
And then let's actually call it here.

523
00:24:43,640 --> 00:24:45,383
So this.#clearInput.

524
00:24:51,601 --> 00:24:52,434
And then of course,

525
00:24:52,434 --> 00:24:55,923
we first need to store this somewhere here.

526
00:25:00,500 --> 00:25:01,980
So we get the query,

527
00:25:01,980 --> 00:25:03,340
then we clear the field

528
00:25:04,220 --> 00:25:06,173
and then we return the query.

529
00:25:08,150 --> 00:25:10,963
All right, so that should now work.

530
00:25:13,674 --> 00:25:16,280
So pasta and clears the field,

531
00:25:16,280 --> 00:25:21,053
and gives us or 45 results down here about pasta.

532
00:25:22,050 --> 00:25:25,810
Great, so that works just fine.

533
00:25:25,810 --> 00:25:27,500
And so, all there's left to do

534
00:25:27,500 --> 00:25:31,110
is to now implement actually the view.

535
00:25:31,110 --> 00:25:33,290
So the second view basically.

536
00:25:33,290 --> 00:25:34,670
So the one

537
00:25:34,670 --> 00:25:35,690
that is responsible

538
00:25:35,690 --> 00:25:37,960
for then rendering all the results

539
00:25:37,960 --> 00:25:39,800
here in this sidebar.

540
00:25:39,800 --> 00:25:42,400
And so that's going to be a little bit of work.

541
00:25:42,400 --> 00:25:44,633
So let's leave that for the next video.

