1
00:00:02,000 --> 00:00:05,000
This here is basically an example

2
00:00:05,000 --> 00:00:08,000
I showed you earlier in this module already.

3
00:00:08,000 --> 00:00:11,000
This is a standard React App,

4
00:00:11,000 --> 00:00:13,000
not using Next.js at all,

5
00:00:13,000 --> 00:00:16,000
which uses a very traditional approach

6
00:00:16,000 --> 00:00:19,000
of sending a request inside of useEffect

7
00:00:19,000 --> 00:00:21,000
once this component is rendered,

8
00:00:21,000 --> 00:00:22,000
setting some loading state

9
00:00:22,000 --> 00:00:26,000
and then displaying some data down there.

10
00:00:26,000 --> 00:00:29,000
Again, that's a very standard React's way.

11
00:00:29,000 --> 00:00:32,000
And of course there are ways of changing that,

12
00:00:32,000 --> 00:00:34,000
of handling errors.

13
00:00:34,000 --> 00:00:37,000
Of using custom hoax and a lot of other things.

14
00:00:37,000 --> 00:00:40,000
But this is the most basic form

15
00:00:40,000 --> 00:00:45,000
of sending a request from inside React on the client side.

16
00:00:45,000 --> 00:00:46,000
And in the end,

17
00:00:46,000 --> 00:00:49,000
that's kind of what we now wanna build again

18
00:00:49,000 --> 00:00:52,000
with Next.js here.

19
00:00:52,000 --> 00:00:55,000
Now, for this I'll add a new page here,

20
00:00:55,000 --> 00:00:57,000
a new route therefore.

21
00:00:57,000 --> 00:01:01,000
And I'll name it last-sales.js.

22
00:01:01,000 --> 00:01:04,000
Of course, this will just be a dummy page here.

23
00:01:04,000 --> 00:01:07,000
This overall project is just a dummy project.

24
00:01:07,000 --> 00:01:10,000
We're going to have a more realistic example

25
00:01:10,000 --> 00:01:11,000
in the next course section,

26
00:01:11,000 --> 00:01:15,000
when we applied as to our events project again.

27
00:01:15,000 --> 00:01:19,000
But in this dummy file here, in this dummy page.

28
00:01:19,000 --> 00:01:21,000
I want to show you how we could implement

29
00:01:21,000 --> 00:01:25,000
client side data fetching with Next.js.

30
00:01:25,000 --> 00:01:27,000
And of course it starts

31
00:01:27,000 --> 00:01:31,000
with defining our page component here.

32
00:01:31,000 --> 00:01:35,000
And of course we also want to export that component

33
00:01:35,000 --> 00:01:36,000
so that it can be found.

34
00:01:37,000 --> 00:01:40,000
Now in here, in that component,

35
00:01:40,000 --> 00:01:42,000
we wanna return some JS Xcode.

36
00:01:42,000 --> 00:01:44,000
Let's say some sales data

37
00:01:44,000 --> 00:01:47,000
which should be rendered as a list,

38
00:01:47,000 --> 00:01:48,000
but we wanna fetch that data

39
00:01:48,000 --> 00:01:52,000
from inside this component function as well.

40
00:01:52,000 --> 00:01:54,000
We don't wanna add get static props

41
00:01:54,000 --> 00:01:56,000
or get server-side props here,

42
00:01:56,000 --> 00:01:59,000
because that's exactly not our goal here.

43
00:01:59,000 --> 00:02:02,000
We don't want to pre-fetch the data on the server

44
00:02:02,000 --> 00:02:04,000
or during the build time.

45
00:02:04,000 --> 00:02:08,000
Inside here, we can now write useEffect.

46
00:02:08,000 --> 00:02:10,000
So use to useEffect hook,

47
00:02:10,000 --> 00:02:13,000
which we import from React therefore.

48
00:02:13,000 --> 00:02:15,000
And then in there, in this effect function

49
00:02:15,000 --> 00:02:20,000
we can execute some code, which sends our HTTP request.

50
00:02:20,000 --> 00:02:21,000
And for a useEffect

51
00:02:21,000 --> 00:02:23,000
we also need to add this dependencies array,

52
00:02:23,000 --> 00:02:26,000
listing all the dependencies of this useEffect function.

53
00:02:26,000 --> 00:02:28,000
And in this case this function

54
00:02:28,000 --> 00:02:30,000
won't have any dependencies

55
00:02:30,000 --> 00:02:34,000
since I won't use any other component specific data here.

56
00:02:35,000 --> 00:02:39,000
So, now in here, we can use the built-in fetch API

57
00:02:39,000 --> 00:02:41,000
which is available in the browser.

58
00:02:41,000 --> 00:02:44,000
And as a side note, which could also be used

59
00:02:44,000 --> 00:02:47,000
in get static props or get service I props.

60
00:02:47,000 --> 00:02:49,000
It is available there as well.

61
00:02:49,000 --> 00:02:51,000
We don't need it there right now,

62
00:02:51,000 --> 00:02:53,000
but you could use it there as well.

63
00:02:53,000 --> 00:02:57,000
But here we use it on the client side instead of useEffect,

64
00:02:57,000 --> 00:02:59,000
to send the request to some API,

65
00:02:59,000 --> 00:03:01,000
to some web server.

66
00:03:01,000 --> 00:03:03,000
Now to test this,

67
00:03:03,000 --> 00:03:05,000
we need some dummy back-end,

68
00:03:05,000 --> 00:03:07,000
we need some web server.

69
00:03:07,000 --> 00:03:10,000
And I will use Firebase for that.

70
00:03:10,000 --> 00:03:12,000
It sounds like it's just a database,

71
00:03:12,000 --> 00:03:15,000
but actually Firebase is a service offered by Google,

72
00:03:15,000 --> 00:03:18,000
which gives you an entire back-end

73
00:03:18,000 --> 00:03:20,000
with a lot of different features.

74
00:03:20,000 --> 00:03:24,000
But one of the features is a database with an attached API

75
00:03:24,000 --> 00:03:26,000
which we can use as a dummy backend here.

76
00:03:26,000 --> 00:03:30,000
So we're not going to build anything complex with Firebase.

77
00:03:30,000 --> 00:03:33,000
We're just going to use it as a dummy back-end.

78
00:03:33,000 --> 00:03:35,000
For this you need to go to the console

79
00:03:35,000 --> 00:03:36,000
and for this you need a Google account

80
00:03:36,000 --> 00:03:38,000
with which you should log in.

81
00:03:39,000 --> 00:03:40,000
And once you did log in,

82
00:03:40,000 --> 00:03:44,000
you can add a new Firebase project

83
00:03:44,000 --> 00:03:47,000
and I'll just name it nextjs-course.

84
00:03:47,000 --> 00:03:47,000
But you can of course

85
00:03:47,000 --> 00:03:51,000
pick any name you want, click continue.

86
00:03:51,000 --> 00:03:52,000
You can disable Google Analytics,

87
00:03:52,000 --> 00:03:53,000
we don't need that.

88
00:03:53,000 --> 00:03:55,000
And create that project.

89
00:03:55,000 --> 00:04:00,000
Again Firebase is a service totally detached from Next.js

90
00:04:00,000 --> 00:04:04,000
which is actually made up of a lot of different services

91
00:04:04,000 --> 00:04:06,000
and tools and utilities,

92
00:04:06,000 --> 00:04:09,000
which you can use to build powerful back-ends

93
00:04:09,000 --> 00:04:12,000
for your application front-ends.

94
00:04:12,000 --> 00:04:15,000
Here, I really just wanna use its built-in database

95
00:04:15,000 --> 00:04:18,000
with a connected API.

96
00:04:18,000 --> 00:04:21,000
And that will be the real time database

97
00:04:21,000 --> 00:04:23,000
which I wanna use.

98
00:04:23,000 --> 00:04:26,000
So, here I'll click on real-time database on the left.

99
00:04:26,000 --> 00:04:30,000
And there, we then can click on create database.

100
00:04:30,000 --> 00:04:33,000
Now you can leave the default here, click on next.

101
00:04:33,000 --> 00:04:35,000
And on security rules

102
00:04:35,000 --> 00:04:37,000
you wanna start in test mode actually,

103
00:04:37,000 --> 00:04:40,000
which ensures that we do have access

104
00:04:40,000 --> 00:04:42,000
to the database from outside.

105
00:04:43,000 --> 00:04:46,000
Now this will create such a database for you.

106
00:04:46,000 --> 00:04:48,000
The great thing is that it will be a database

107
00:04:48,000 --> 00:04:51,000
into which we can look into here.

108
00:04:51,000 --> 00:04:55,000
And we also get an API here to which we can send requests

109
00:04:55,000 --> 00:04:59,000
which will then automatically be translated

110
00:04:59,000 --> 00:05:02,000
into database operations by Firebase.

111
00:05:02,000 --> 00:05:06,000
So, we send regular HTTP requests to this API here

112
00:05:06,000 --> 00:05:09,000
and then automatically data gets written, deleted

113
00:05:09,000 --> 00:05:13,000
whatever we wanna do here in Firebase.

114
00:05:13,000 --> 00:05:16,000
Now, here I actually wanna prepare some data though.

115
00:05:16,000 --> 00:05:18,000
So that we have some data we can fetch

116
00:05:18,000 --> 00:05:21,000
with our Next.js code here.

117
00:05:22,000 --> 00:05:24,000
Therefore we can click on the plus here,

118
00:05:24,000 --> 00:05:28,000
when we hover over this database name.

119
00:05:28,000 --> 00:05:31,000
And then add any key of your choice.

120
00:05:31,000 --> 00:05:33,000
I'll go with sales here,

121
00:05:33,000 --> 00:05:35,000
and then click on the plus here.

122
00:05:35,000 --> 00:05:38,000
And now we basically created a sales node

123
00:05:38,000 --> 00:05:41,000
a sales table kind off,

124
00:05:41,000 --> 00:05:44,000
and we can now add a different pieces of information

125
00:05:44,000 --> 00:05:46,000
that belong to a single sale.

126
00:05:46,000 --> 00:05:50,000
For example, here, we could name this first sale

127
00:05:50,000 --> 00:05:53,000
which you wanna add s1 and click on the plus again

128
00:05:53,000 --> 00:05:56,000
and now add the data that belongs to that sale.

129
00:05:56,000 --> 00:06:00,000
Like for example, the username, which could be Max,

130
00:06:01,000 --> 00:06:02,000
click on add now.

131
00:06:02,000 --> 00:06:05,000
And then click on the plus next to s1 again,

132
00:06:05,000 --> 00:06:08,000
and also add a volume of let's say 100.

133
00:06:10,000 --> 00:06:13,000
And now let's click on the plus next to sales again,

134
00:06:13,000 --> 00:06:17,000
add a sale with a name of s2 and click on this plus.

135
00:06:17,000 --> 00:06:21,000
And here add a username of manual,

136
00:06:21,000 --> 00:06:24,000
and then click on the plus next to s2,

137
00:06:24,000 --> 00:06:26,000
and add a volume of 50.

138
00:06:26,000 --> 00:06:28,000
Click on add.

139
00:06:28,000 --> 00:06:32,000
And now we added two sales entries to this dummy database.

140
00:06:34,000 --> 00:06:36,000
Now I mentioned that it would be this URL

141
00:06:37,000 --> 00:06:39,000
which we can use to send the request to,

142
00:06:39,000 --> 00:06:41,000
to interact with that database.

143
00:06:41,000 --> 00:06:43,000
And that is correct.

144
00:06:43,000 --> 00:06:45,000
I'll copy that URL.

145
00:06:45,000 --> 00:06:47,000
And now here in fetch,

146
00:06:47,000 --> 00:06:51,000
we can use that URL at least as a starter.

147
00:06:51,000 --> 00:06:54,000
And then here, we wanna send the request to the sales node

148
00:06:54,000 --> 00:06:56,000
and fetch all the sales.

149
00:06:56,000 --> 00:06:58,000
So, here I'll then add slash sales.

150
00:06:58,000 --> 00:07:00,000
And now in Firebase world,

151
00:07:00,000 --> 00:07:03,000
we also need to add dot json at the end.

152
00:07:03,000 --> 00:07:06,000
This is not a Next.js requirement.

153
00:07:06,000 --> 00:07:08,000
This is really just required

154
00:07:08,000 --> 00:07:11,000
by this Firebase API we're using.

155
00:07:11,000 --> 00:07:14,000
And this will send a request to this sales node

156
00:07:14,000 --> 00:07:16,000
in this Firebase database.

157
00:07:16,000 --> 00:07:18,000
Again, we just use it as a dummy back-end here.

158
00:07:20,000 --> 00:07:24,000
Now, fetch this built-in browser API,

159
00:07:24,000 --> 00:07:26,000
this function which is built into the browser,

160
00:07:26,000 --> 00:07:28,000
then returns a promise.

161
00:07:28,000 --> 00:07:31,000
So, here we can add a then block

162
00:07:31,000 --> 00:07:33,000
to work with the response

163
00:07:33,000 --> 00:07:35,000
which we actually get back here.

164
00:07:35,000 --> 00:07:37,000
And on this response,

165
00:07:37,000 --> 00:07:42,000
we can call dot json to read the data from that response.

166
00:07:42,000 --> 00:07:44,000
That's how this fetch API works.

167
00:07:44,000 --> 00:07:46,000
Again, nothing Next.js specific.

168
00:07:46,000 --> 00:07:49,000
This is the standard browser fetch API

169
00:07:49,000 --> 00:07:50,000
and how we can use it.

170
00:07:52,000 --> 00:07:54,000
So now with that, we're taking the response

171
00:07:54,000 --> 00:07:57,000
and extracting the response data.

172
00:07:57,000 --> 00:07:59,000
This again, then returns a promise.

173
00:07:59,000 --> 00:08:02,000
So we can chain another then call here

174
00:08:02,000 --> 00:08:04,000
and this will then give us the actual data

175
00:08:04,000 --> 00:08:06,000
which we parsed from the response.

176
00:08:07,000 --> 00:08:11,000
And it's now in here in this function here,

177
00:08:11,000 --> 00:08:13,000
where we can use that data which we received.

178
00:08:15,000 --> 00:08:18,000
Now, we might want to update the state of this component

179
00:08:18,000 --> 00:08:20,000
to output the data down there,

180
00:08:20,000 --> 00:08:22,000
once we did get it.

181
00:08:22,000 --> 00:08:26,000
And for this we can import to useState hook here.

182
00:08:26,000 --> 00:08:29,000
And register a state in this component.

183
00:08:29,000 --> 00:08:34,000
Let's say the data state or the sales state

184
00:08:36,000 --> 00:08:40,000
with a setSales state updating function.

185
00:08:40,000 --> 00:08:43,000
And we call useState to initialize this state.

186
00:08:43,000 --> 00:08:46,000
And initially let's say that's undefined

187
00:08:46,000 --> 00:08:49,000
because initially we have no sales.

188
00:08:49,000 --> 00:08:52,000
And maybe we also want a loading state,

189
00:08:52,000 --> 00:08:54,000
the isLoading state,

190
00:08:54,000 --> 00:08:56,000
so that we can show some loading fallback

191
00:08:56,000 --> 00:08:59,000
whilst we're waiting for that data to arrive.

192
00:08:59,000 --> 00:09:03,000
So here I'll then also set up this state

193
00:09:03,000 --> 00:09:05,000
and initially it's false.

194
00:09:07,000 --> 00:09:10,000
And now in useEffect in this function,

195
00:09:10,000 --> 00:09:13,000
we wanna set isLoading to true here at the beginning

196
00:09:13,000 --> 00:09:16,000
to set this loading state to true,

197
00:09:16,000 --> 00:09:18,000
because we are now fetching data.

198
00:09:18,000 --> 00:09:22,000
And once we got the data here in this second then block,

199
00:09:22,000 --> 00:09:26,000
we wanna setSales equal to our sales data.

200
00:09:26,000 --> 00:09:28,000
And, balloon that in a second.

201
00:09:28,000 --> 00:09:33,000
And we also want to set isLoading to false here again,

202
00:09:34,000 --> 00:09:35,000
because we're not loading anymore.

203
00:09:36,000 --> 00:09:38,000
Now regarding the sales data,

204
00:09:38,000 --> 00:09:40,000
it is important to know

205
00:09:40,000 --> 00:09:42,000
that the data we'll get back from Firebase

206
00:09:42,000 --> 00:09:44,000
will not be an array,

207
00:09:44,000 --> 00:09:47,000
but it will be an object where these Ids here,

208
00:09:47,000 --> 00:09:50,000
s1 and s2 will be keys,

209
00:09:50,000 --> 00:09:54,000
which then holds the detailed data as nested objects.

210
00:09:54,000 --> 00:09:58,000
So, if we want an array, we need to transform this data.

211
00:09:58,000 --> 00:10:01,000
So, here we can have our transformedSales

212
00:10:02,000 --> 00:10:04,000
which is an array.

213
00:10:04,000 --> 00:10:07,000
And we built that with a four in loop,

214
00:10:07,000 --> 00:10:10,000
by looping through all the keys in data.

215
00:10:10,000 --> 00:10:12,000
Because again, data will be an object

216
00:10:12,000 --> 00:10:17,000
where our Ids s1 and s2 will be keys.

217
00:10:18,000 --> 00:10:20,000
So then for transformedSales,

218
00:10:20,000 --> 00:10:22,000
we push an object into this array.

219
00:10:22,000 --> 00:10:25,000
And that object maybe has an Id property,

220
00:10:25,000 --> 00:10:27,000
which has the key as a value,

221
00:10:27,000 --> 00:10:30,000
because again, the keys are these Ids.

222
00:10:32,000 --> 00:10:35,000
And then we have our username field

223
00:10:35,000 --> 00:10:38,000
which is data for the given key.

224
00:10:38,000 --> 00:10:41,000
Dynamically accessing it with the square brackets,

225
00:10:41,000 --> 00:10:45,000
which is standard JavaScript dot username.

226
00:10:45,000 --> 00:10:48,000
So now we're diving into that nested object here,

227
00:10:48,000 --> 00:10:50,000
accessing the username.

228
00:10:50,000 --> 00:10:52,000
And we wanna do the same for the volume.

229
00:10:52,000 --> 00:10:55,000
So, I'll set a volume key here

230
00:10:55,000 --> 00:11:00,000
and set this equal to data for the given key dot volume.

231
00:11:01,000 --> 00:11:03,000
Now I'll reformat this and it looks like this.

232
00:11:05,000 --> 00:11:08,000
So now this is how we transform our sales

233
00:11:08,000 --> 00:11:11,000
from an object to an array.

234
00:11:11,000 --> 00:11:16,000
And then I can set these transformedSales as my new sales.

235
00:11:17,000 --> 00:11:20,000
And that would be a very standard reactive way

236
00:11:20,000 --> 00:11:22,000
of sending such a request.

237
00:11:23,000 --> 00:11:28,000
We can now use it and check if we are loading here.

238
00:11:28,000 --> 00:11:31,000
And if we are, I return a paragraph where I say,

239
00:11:31,000 --> 00:11:33,000
loading let's say,

240
00:11:33,000 --> 00:11:36,000
or where we show some loading spinner off course.

241
00:11:36,000 --> 00:11:38,000
And otherwise here in the unordered list,

242
00:11:38,000 --> 00:11:43,000
we can also access our sales then, our sales state.

243
00:11:43,000 --> 00:11:45,000
And map our sales

244
00:11:45,000 --> 00:11:50,000
so that every sale is mapped into a list item

245
00:11:50,000 --> 00:11:53,000
where the key is set to sale.id

246
00:11:53,000 --> 00:11:57,000
and where we then output the sale username.

247
00:11:57,000 --> 00:11:59,000
Then a dash maybe,

248
00:12:00,000 --> 00:12:04,000
and then after that the sale volume

249
00:12:04,000 --> 00:12:06,000
and maybe a dollar sign in front of it

250
00:12:06,000 --> 00:12:08,000
but that's just cosmetics.

251
00:12:10,000 --> 00:12:12,000
With all of that in place,

252
00:12:12,000 --> 00:12:15,000
we now got this client-side code.

253
00:12:15,000 --> 00:12:17,000
Now we can spin up our development server again

254
00:12:17,000 --> 00:12:19,000
to preview this.

255
00:12:19,000 --> 00:12:23,000
For this I'll go to local host last dash sales,

256
00:12:23,000 --> 00:12:26,000
since that last a page name we added.

257
00:12:26,000 --> 00:12:27,000
And here I get an error

258
00:12:27,000 --> 00:12:30,000
cannot read property map of undefined.

259
00:12:30,000 --> 00:12:33,000
That makes a lot of sense because initially

260
00:12:33,000 --> 00:12:35,000
isLoading is false.

261
00:12:36,000 --> 00:12:38,000
And our sales state

262
00:12:38,000 --> 00:12:41,000
which we try to use down there is undefined.

263
00:12:41,000 --> 00:12:44,000
Now in useEffect we change this loading state,

264
00:12:44,000 --> 00:12:46,000
but the way React works

265
00:12:46,000 --> 00:12:49,000
is such that useEffect only executes the effect function

266
00:12:49,000 --> 00:12:52,000
after the whole component was evaluated

267
00:12:52,000 --> 00:12:55,000
and rendered for the first time.

268
00:12:55,000 --> 00:12:57,000
And for this first render cycle

269
00:12:57,000 --> 00:12:59,000
sales therefore will be undefined

270
00:12:59,000 --> 00:13:01,000
and state will be false.

271
00:13:01,000 --> 00:13:02,000
So we'll reach that code

272
00:13:02,000 --> 00:13:04,000
and we'll then try to call map

273
00:13:04,000 --> 00:13:06,000
on something which is undefined.

274
00:13:07,000 --> 00:13:08,000
So therefore I'll add another check

275
00:13:08,000 --> 00:13:10,000
and check if not sales.

276
00:13:10,000 --> 00:13:13,000
So if we have no sales yet,

277
00:13:13,000 --> 00:13:18,000
in which case I return no data yet here as a paragraph.

278
00:13:19,000 --> 00:13:21,000
Now with data, if we save this,

279
00:13:21,000 --> 00:13:23,000
with this extra check added,

280
00:13:23,000 --> 00:13:25,000
now if I reload you see loading

281
00:13:25,000 --> 00:13:27,000
and then you see that data eventually.

282
00:13:27,000 --> 00:13:30,000
And that is how we could fetch data on the client side.

283
00:13:31,000 --> 00:13:34,000
Now, if we inspect the page source here,

284
00:13:34,000 --> 00:13:38,000
then the interesting thing is that we see no data yet.

285
00:13:38,000 --> 00:13:41,000
And that hopefully makes sense.

286
00:13:41,000 --> 00:13:45,000
The pages still pre-rendered by Next.js.

287
00:13:45,000 --> 00:13:47,000
Because I explained earlier in this module

288
00:13:47,000 --> 00:13:50,000
that that would be the default page

289
00:13:50,000 --> 00:13:53,000
which does not use get server side props,

290
00:13:53,000 --> 00:13:57,000
effectively will be pre-rendered by Next.js.

291
00:13:57,000 --> 00:14:01,000
The key thing here just is that the data used by this page

292
00:14:01,000 --> 00:14:04,000
will not be prepared by Next.js

293
00:14:04,000 --> 00:14:06,000
with get static props for example.

294
00:14:07,000 --> 00:14:11,000
Hence, when Next.js pre renders this page,

295
00:14:11,000 --> 00:14:13,000
it will not execute useEffect.

296
00:14:13,000 --> 00:14:15,000
It will not wait for this.

297
00:14:15,000 --> 00:14:16,000
It will not care about that.

298
00:14:16,000 --> 00:14:18,000
It will just return

299
00:14:18,000 --> 00:14:22,000
and pre-render the very basic first version

300
00:14:22,000 --> 00:14:24,000
of what this component spits out.

301
00:14:24,000 --> 00:14:26,000
And that has no data yet

302
00:14:26,000 --> 00:14:29,000
for the reasons I explained a couple of seconds ago.

303
00:14:29,000 --> 00:14:32,000
That is the initial state of this page.

304
00:14:32,000 --> 00:14:36,000
And that is what gets pre-rendered therefore.

305
00:14:36,000 --> 00:14:39,000
So we still have pre-rendering going on,

306
00:14:39,000 --> 00:14:40,000
but without the data.

307
00:14:40,000 --> 00:14:44,000
Because we're fetching the data on the client side now,

308
00:14:44,000 --> 00:14:45,000
with this approach.

