1
00:00:02,000 --> 00:00:05,000
So now we did add static generation

2
00:00:05,000 --> 00:00:09,000
and server side rendering to this mini application here.

3
00:00:09,000 --> 00:00:13,000
What about client-side data fetching though?

4
00:00:13,000 --> 00:00:15,000
Do we need that as well?

5
00:00:15,000 --> 00:00:18,000
To be honest in this application,

6
00:00:18,000 --> 00:00:21,000
I would argue that we don't really need it,

7
00:00:21,000 --> 00:00:23,000
but we could still add it on a page

8
00:00:23,000 --> 00:00:27,000
where I think that it would also be okay.

9
00:00:27,000 --> 00:00:29,000
And that's this filter page,

10
00:00:29,000 --> 00:00:34,000
there we are currently using getServerSideProps, that works,

11
00:00:34,000 --> 00:00:36,000
but I think here client-side site data fetching

12
00:00:36,000 --> 00:00:38,000
could also be okay.

13
00:00:38,000 --> 00:00:41,000
By using that the page would load a bit quicker

14
00:00:41,000 --> 00:00:44,000
because we don't need to pre-render it on the server,

15
00:00:44,000 --> 00:00:48,000
but of course therefore the data would initially be missing.

16
00:00:48,000 --> 00:00:50,000
So we need to show some loading state

17
00:00:50,000 --> 00:00:52,000
until the data is there.

18
00:00:52,000 --> 00:00:55,000
But I think this page would be a fine page

19
00:00:55,000 --> 00:00:57,000
for a client-side data fetching,

20
00:00:57,000 --> 00:01:02,000
because it might be nice to get to this page quickly.

21
00:01:02,000 --> 00:01:06,000
And in addition, it's not that important for search engines.

22
00:01:06,000 --> 00:01:09,000
I mean this filtered list of events,

23
00:01:09,000 --> 00:01:14,000
that's not the main thing search engines should be crawling,

24
00:01:14,000 --> 00:01:17,000
for them, the featured events, all events

25
00:01:17,000 --> 00:01:20,000
and the event details are more relevant.

26
00:01:21,000 --> 00:01:23,000
So therefore I think we could use

27
00:01:23,000 --> 00:01:25,000
client-side data fetching here

28
00:01:25,000 --> 00:01:27,000
on that filtered events page,

29
00:01:28,000 --> 00:01:30,000
that does not mean

30
00:01:30,000 --> 00:01:33,000
that you typically replace getServiceSideProps

31
00:01:33,000 --> 00:01:35,000
with client-side data fetching.

32
00:01:35,000 --> 00:01:40,000
It just happens to fit in quite well in this exact scenario.

33
00:01:41,000 --> 00:01:44,000
Therefore, in this slug page,

34
00:01:44,000 --> 00:01:47,000
I'll comment this code here back in,

35
00:01:47,000 --> 00:01:50,000
because now for a client-side data fetching,

36
00:01:50,000 --> 00:01:54,000
we again need access to the route parameters

37
00:01:54,000 --> 00:01:56,000
inside of this component function

38
00:01:56,000 --> 00:01:59,000
because that is where we are going to write

39
00:01:59,000 --> 00:02:01,000
that data fetching code.

40
00:02:01,000 --> 00:02:03,000
And we definitely, for example,

41
00:02:03,000 --> 00:02:05,000
still need some loading state,

42
00:02:05,000 --> 00:02:07,000
which should eventually be displayed.

43
00:02:08,000 --> 00:02:13,000
Now I wanna do the data fetching with this useSWR hook,

44
00:02:13,000 --> 00:02:15,000
which i showed you in the last course section.

45
00:02:15,000 --> 00:02:19,000
So I'll quit the development server temporarily

46
00:02:19,000 --> 00:02:22,000
and install the SWR package,

47
00:02:22,000 --> 00:02:25,000
which brings us that hook,

48
00:02:25,000 --> 00:02:29,000
and thereafter we can restart the development server.

49
00:02:30,000 --> 00:02:33,000
Now here in the slug page,

50
00:02:33,000 --> 00:02:38,000
we can import useSWR from this SWR package.

51
00:02:38,000 --> 00:02:41,000
And then we can start using it.

52
00:02:41,000 --> 00:02:44,000
Here after I got my filter data,

53
00:02:44,000 --> 00:02:47,000
so after I got the route parameters,

54
00:02:47,000 --> 00:02:52,000
I will call useSWR and then we wanna send a request

55
00:02:54,000 --> 00:02:59,000
and I wanna send a request to firebase for filtered events.

56
00:03:00,000 --> 00:03:04,000
Now again, we can add that filtering logic with firebase,

57
00:03:04,000 --> 00:03:07,000
but since it's not the focus here,

58
00:03:07,000 --> 00:03:11,000
I'll cheat and that will instead fetch all events

59
00:03:11,000 --> 00:03:14,000
and then filter here in this component,

60
00:03:14,000 --> 00:03:16,000
which is of course sub optimal,

61
00:03:16,000 --> 00:03:18,000
but good enough for this example.

62
00:03:18,000 --> 00:03:21,000
So therefore again, I'll grab this link,

63
00:03:21,000 --> 00:03:23,000
which fetches all events

64
00:03:24,000 --> 00:03:29,000
and use that as that key for useSWR.

65
00:03:29,000 --> 00:03:30,000
And that then as you learned,

66
00:03:30,000 --> 00:03:32,000
gives us back an object

67
00:03:32,000 --> 00:03:35,000
where we get access to the fetched data,

68
00:03:35,000 --> 00:03:39,000
and also to a possible error we might be getting.

69
00:03:40,000 --> 00:03:44,000
Now, we also still need to transform the data though

70
00:03:44,000 --> 00:03:45,000
that doesn't change.

71
00:03:45,000 --> 00:03:49,000
This transformation still needs to be applied.

72
00:03:49,000 --> 00:03:52,000
So therefore I'll copy that transformation logic,

73
00:03:52,000 --> 00:03:56,000
and add it to this slug page with help of useEffect,

74
00:03:56,000 --> 00:03:59,000
which we need to import from react.

75
00:03:59,000 --> 00:04:00,000
And whilst we're there,

76
00:04:00,000 --> 00:04:03,000
we can also already import useState

77
00:04:03,000 --> 00:04:05,000
because we'll need that as well.

78
00:04:06,000 --> 00:04:10,000
So now we're here after using useSWR,

79
00:04:11,000 --> 00:04:15,000
I'll execute useEffect and pass an effect function to it.

80
00:04:15,000 --> 00:04:17,000
And as a dependency, I'll add data

81
00:04:17,000 --> 00:04:19,000
because this effect should rerun,

82
00:04:19,000 --> 00:04:23,000
whenever the day that we fetched changes.

83
00:04:23,000 --> 00:04:25,000
Then I'll check if we do have data,

84
00:04:25,000 --> 00:04:29,000
because if we don't, there's nothing we need to do.

85
00:04:29,000 --> 00:04:32,000
And if we do have data, I wanna transform it.

86
00:04:32,000 --> 00:04:34,000
So I paste in my transformation logic

87
00:04:34,000 --> 00:04:39,000
to transform the incoming data into such an events array.

88
00:04:39,000 --> 00:04:42,000
However, that array should not be returned here,

89
00:04:42,000 --> 00:04:45,000
instead it should be set as state,

90
00:04:45,000 --> 00:04:48,000
so we can register some state here,

91
00:04:48,000 --> 00:04:49,000
which is initially undefined.

92
00:04:50,000 --> 00:04:53,000
The events state

93
00:04:57,000 --> 00:05:00,000
with setEvents as a state updating function.

94
00:05:01,000 --> 00:05:04,000
And then in here, I'll call setEvents

95
00:05:04,000 --> 00:05:08,000
and set this equal to my events which I have here.

96
00:05:08,000 --> 00:05:12,000
So to this events array, not events state,

97
00:05:12,000 --> 00:05:13,000
in case this is confusing,

98
00:05:13,000 --> 00:05:16,000
I can also name this loadedEvents and setLoadedEvents.

99
00:05:20,000 --> 00:05:23,000
And then now they are setLoadedEvents

100
00:05:23,000 --> 00:05:25,000
equal to the events array we're generating here.

101
00:05:27,000 --> 00:05:28,000
Now, of course it's very possible

102
00:05:28,000 --> 00:05:31,000
that we don't have any loadedEvents,

103
00:05:31,000 --> 00:05:33,000
especially when this component is rendered

104
00:05:33,000 --> 00:05:34,000
for the first time.

105
00:05:34,000 --> 00:05:37,000
So before fetching data has even started.

106
00:05:37,000 --> 00:05:40,000
So if we not have loadedEvents,

107
00:05:40,000 --> 00:05:43,000
then I wanna show this loading output here.

108
00:05:44,000 --> 00:05:47,000
Otherwise we make it past this if check,

109
00:05:47,000 --> 00:05:50,000
and then in this case,

110
00:05:50,000 --> 00:05:54,000
we get the filtered year and month we convert that

111
00:05:54,000 --> 00:05:58,000
and we can then use that data to extract just events

112
00:05:58,000 --> 00:06:00,000
which you wanna display here.

113
00:06:00,000 --> 00:06:02,000
Again that is sub-optimal,

114
00:06:02,000 --> 00:06:06,000
normally we would want to fetch just the right events,

115
00:06:06,000 --> 00:06:09,000
but since this would be very firebase specific,

116
00:06:09,000 --> 00:06:11,000
we're going to go with this approach here.

117
00:06:12,000 --> 00:06:17,000
So therefore here, I then wanna use my filtering logic here

118
00:06:17,000 --> 00:06:22,000
from inside the get filteredEvents function in api-util,

119
00:06:22,000 --> 00:06:25,000
copy that over and add it here.

120
00:06:27,000 --> 00:06:29,000
So that i have my filteredEvents here

121
00:06:29,000 --> 00:06:32,000
and instead of all events, that's loadedEvents,

122
00:06:32,000 --> 00:06:35,000
so this state we just added

123
00:06:35,000 --> 00:06:38,000
that will then filter the events appropriately.

124
00:06:38,000 --> 00:06:41,000
However here, I don't wanna compare this with year,

125
00:06:41,000 --> 00:06:44,000
but with numYear and here with numMonth,

126
00:06:47,000 --> 00:06:49,000
so with these two constants.

127
00:06:51,000 --> 00:06:52,000
Now we've got the filtered events,

128
00:06:52,000 --> 00:06:55,000
props.hasError will never be a thing

129
00:06:55,000 --> 00:06:58,000
since we're not using server-side rendering anymore,

130
00:06:58,000 --> 00:07:02,000
which is where this prop was coming from before.

131
00:07:02,000 --> 00:07:06,000
Now we won't use it anymore, I'll soon remove it.

132
00:07:06,000 --> 00:07:09,000
So that's no longer something we should check.

133
00:07:09,000 --> 00:07:12,000
Instead here, I wanna bring back this if check,

134
00:07:12,000 --> 00:07:15,000
which we outsourced to get server-side props.

135
00:07:15,000 --> 00:07:18,000
Since we're moving back to client-side data fetching,

136
00:07:18,000 --> 00:07:21,000
I'll bring it back onto the client-side.

137
00:07:21,000 --> 00:07:25,000
So this is my if condition now,

138
00:07:28,000 --> 00:07:29,000
like this,

139
00:07:29,000 --> 00:07:31,000
and it might make sense to check this

140
00:07:31,000 --> 00:07:36,000
before we try to filter, so I'll grab this code here

141
00:07:37,000 --> 00:07:40,000
and actually check this here

142
00:07:40,000 --> 00:07:42,000
before we derive the filtered events.

143
00:07:44,000 --> 00:07:48,000
So if we make it past this check, we can filter for events.

144
00:07:49,000 --> 00:07:51,000
We no longer need that line now.

145
00:07:51,000 --> 00:07:54,000
And then we check if we, do we have filtered events?

146
00:07:54,000 --> 00:07:57,000
Or to be precise, if we don't have filtered events,

147
00:07:57,000 --> 00:07:59,000
in which case we show this fallback

148
00:07:59,000 --> 00:08:04,000
and otherwise we still wanna display the filtered events.

149
00:08:04,000 --> 00:08:08,000
And down there we can now again use numYear and numMonth

150
00:08:08,000 --> 00:08:11,000
since I brought back those values here.

151
00:08:13,000 --> 00:08:14,000
So with all of that,

152
00:08:14,000 --> 00:08:17,000
we should be fetching the data on the client-side

153
00:08:17,000 --> 00:08:19,000
with the useSWR hook.

154
00:08:19,000 --> 00:08:21,000
Now here we might have an error.

155
00:08:21,000 --> 00:08:25,000
So that's also something this error, this http error,

156
00:08:25,000 --> 00:08:29,000
which we might be getting, which we should consider,

157
00:08:29,000 --> 00:08:30,000
and I'll simply check here.

158
00:08:30,000 --> 00:08:35,000
Or if we have an error, then I wanna show this error output.

159
00:08:35,000 --> 00:08:37,000
Of course you could also handle it separately.

160
00:08:38,000 --> 00:08:39,000
And with all that added,

161
00:08:39,000 --> 00:08:42,000
we brought client-side data fetching back.

162
00:08:42,000 --> 00:08:43,000
And that means of course,

163
00:08:43,000 --> 00:08:47,000
that we should now remove getServiceSideProps.

164
00:08:47,000 --> 00:08:50,000
Having both together, doesn't make a lot of sense.

165
00:08:50,000 --> 00:08:53,000
It can make sense to have, getStaticProps

166
00:08:53,000 --> 00:08:55,000
with client-side fetching

167
00:08:55,000 --> 00:08:58,000
so that you have some pre-rendered page

168
00:08:58,000 --> 00:09:01,000
and you then update it with client-side fetching,

169
00:09:01,000 --> 00:09:03,000
but getServiceSideProps

170
00:09:03,000 --> 00:09:05,000
and client-side fetching makes no sense

171
00:09:05,000 --> 00:09:09,000
because getServiceSideProps is re-executed

172
00:09:09,000 --> 00:09:11,000
for every request anyways.

173
00:09:11,000 --> 00:09:14,000
So you are guaranteed to have the latest data there.

174
00:09:14,000 --> 00:09:17,000
So if you use client-side data fetching,

175
00:09:17,000 --> 00:09:18,000
as we are doing it here,

176
00:09:18,000 --> 00:09:20,000
it makes no sense to use that

177
00:09:20,000 --> 00:09:23,000
in conjunction with getServiceSideProps.

178
00:09:23,000 --> 00:09:27,000
At least not if your concern is having up-to-date data.

179
00:09:27,000 --> 00:09:30,000
it could make sense if you need to look into request headers

180
00:09:30,000 --> 00:09:31,000
or anything like that,

181
00:09:31,000 --> 00:09:35,000
but we're not doing that here, so we can comment this out.

182
00:09:36,000 --> 00:09:39,000
And with all that, if we save all the code again,

183
00:09:39,000 --> 00:09:41,000
if I reload this page here

184
00:09:41,000 --> 00:09:45,000
for a filter where I have no events I see that,

185
00:09:45,000 --> 00:09:49,000
if I enter something invalid, I see that.

186
00:09:49,000 --> 00:09:53,000
And if I do a set of valid filter, I see that.

187
00:09:54,000 --> 00:09:57,000
And if I reload, I see loading at that.

188
00:09:57,000 --> 00:10:00,000
And of course, if we now inspect the page source,

189
00:10:00,000 --> 00:10:03,000
this page is now missing the event data,

190
00:10:03,000 --> 00:10:06,000
instead it only contains that loading text,

191
00:10:06,000 --> 00:10:08,000
because when it was pre-rendered,

192
00:10:08,000 --> 00:10:10,000
we didn't pre-fetch the data,

193
00:10:10,000 --> 00:10:13,000
we didn't prepare the data for the pre rendering.

194
00:10:13,000 --> 00:10:16,000
Since I commented out, getServiceSideProps

195
00:10:16,000 --> 00:10:19,000
and therefore all Next.js saw

196
00:10:19,000 --> 00:10:21,000
when it pre-rendered this page,

197
00:10:21,000 --> 00:10:26,000
was in the end, this loading state this year,

198
00:10:26,000 --> 00:10:28,000
because we don't have any loaded events

199
00:10:28,000 --> 00:10:33,000
the first time this component is rendered by Next.js.

200
00:10:34,000 --> 00:10:37,000
Now as explained using client-side data fetching,

201
00:10:37,000 --> 00:10:39,000
is totally optional here.

202
00:10:39,000 --> 00:10:42,000
There's nothing wrong with getServiceSideProps,

203
00:10:42,000 --> 00:10:44,000
but now we also saw that in action again.

204
00:10:44,000 --> 00:10:46,000
And therefore, hopefully it's now clear

205
00:10:46,000 --> 00:10:50,000
how those different data fetching approaches work,

206
00:10:50,000 --> 00:10:53,000
and when you might wanna consider using which.

