1
00:00:02,000 --> 00:00:06,000
So here on this slug page, on this catch all page,

2
00:00:06,000 --> 00:00:10,000
we're currently getting the concrete path values

3
00:00:10,000 --> 00:00:12,000
from the router,

4
00:00:12,000 --> 00:00:14,000
to then get the year and the month

5
00:00:14,000 --> 00:00:19,000
and fetch the appropriate events for us here.

6
00:00:19,000 --> 00:00:23,000
Now the question is, how do we wanna do that in the future

7
00:00:23,000 --> 00:00:25,000
with our newly gained knowledge?

8
00:00:25,000 --> 00:00:28,000
And we have a couple of options here.

9
00:00:28,000 --> 00:00:32,000
We can use getStaticProps to pre-generate this.

10
00:00:32,000 --> 00:00:35,000
But of course, for the filtered events,

11
00:00:35,000 --> 00:00:39,000
we'll have a lot of different combinations of parameters.

12
00:00:39,000 --> 00:00:44,000
2021, and one, and five, and two, and so on.

13
00:00:44,000 --> 00:00:46,000
That's not necessarily an issue, though,

14
00:00:46,000 --> 00:00:50,000
because we will have to use getStaticPaths anyways,

15
00:00:50,000 --> 00:00:54,000
and once we add that, we could only pre-render a couple

16
00:00:54,000 --> 00:00:58,000
of those combinations, and not all of them.

17
00:00:58,000 --> 00:01:03,000
And instead, then, use fallback set to true or blocking.

18
00:01:03,000 --> 00:01:04,000
But how should we decide

19
00:01:04,000 --> 00:01:07,000
which paths should be pre-generated?

20
00:01:07,000 --> 00:01:12,000
In the end, all possible filters are equally likely

21
00:01:12,000 --> 00:01:13,000
to be visited.

22
00:01:13,000 --> 00:01:16,000
So, I would have a hard time picking a couple

23
00:01:16,000 --> 00:01:20,000
of combinations that should be pre-generated.

24
00:01:20,000 --> 00:01:23,000
And pre-generating all possible combinations

25
00:01:23,000 --> 00:01:25,000
is also not a great option

26
00:01:25,000 --> 00:01:27,000
because that could be a lot of pages.

27
00:01:27,000 --> 00:01:30,000
Especially if we have no year restriction, for example.

28
00:01:32,000 --> 00:01:36,000
So, getStaticProps might not be ideal here.

29
00:01:36,000 --> 00:01:40,000
Maybe, here, getServerSideProps is better.

30
00:01:40,000 --> 00:01:44,000
So that we do indeed fetch the data on the fly

31
00:01:44,000 --> 00:01:47,000
for every incoming request, and we then return the page

32
00:01:47,000 --> 00:01:50,000
for every incoming request.

33
00:01:50,000 --> 00:01:52,000
So let's start with that.

34
00:01:52,000 --> 00:01:57,000
In this slug page, I will export an async function

35
00:02:00,000 --> 00:02:02,000
called getServerSideProps.

36
00:02:04,000 --> 00:02:07,000
You know that here we get the context.

37
00:02:07,000 --> 00:02:09,000
And then here we wanna return an object

38
00:02:09,000 --> 00:02:13,000
which is similar to the object we return in getStaticProps.

39
00:02:13,000 --> 00:02:17,000
With the props key and possibly also with the not found key

40
00:02:17,000 --> 00:02:19,000
and the redirect key if we need it.

41
00:02:21,000 --> 00:02:26,000
Now here, from the context, we can get access to the params.

42
00:02:26,000 --> 00:02:30,000
So here, we can get access to the parameters

43
00:02:30,000 --> 00:02:32,000
for which this page was visited.

44
00:02:32,000 --> 00:02:34,000
And that's good because now,

45
00:02:34,000 --> 00:02:37,000
we basically wanna repeat what we previously did

46
00:02:37,000 --> 00:02:40,000
in our component function.

47
00:02:40,000 --> 00:02:43,000
We wanna get our year and month,

48
00:02:43,000 --> 00:02:45,000
and convert that to a number,

49
00:02:45,000 --> 00:02:47,000
and then validate it,

50
00:02:47,000 --> 00:02:51,000
and then ultimately get our filtered events.

51
00:02:52,000 --> 00:02:54,000
So I will copy all that code,

52
00:02:54,000 --> 00:02:56,000
though we're going to edit it a bit,

53
00:02:56,000 --> 00:02:58,000
but I'll copy all that code,

54
00:02:58,000 --> 00:03:00,000
and bring it down there into getServerSideProps.

55
00:03:02,000 --> 00:03:06,000
Now here, we're accessing filtered data

56
00:03:06,000 --> 00:03:08,000
that should actually be our params.

57
00:03:08,000 --> 00:03:12,000
Because up there, filtered data is also just what we read

58
00:03:12,000 --> 00:03:16,000
from the router query, which are also our params

59
00:03:16,000 --> 00:03:19,000
when accessed through useRouter.

60
00:03:19,000 --> 00:03:22,000
So therefore here I'll rebuild filterData

61
00:03:23,000 --> 00:03:26,000
and access params.slug.

62
00:03:26,000 --> 00:03:27,000
So we still access .slug

63
00:03:27,000 --> 00:03:32,000
because that is our catch-all grouping parameter name,

64
00:03:32,000 --> 00:03:34,000
if you wanna call it like that.

65
00:03:34,000 --> 00:03:38,000
And that will still be an array with multiple values,

66
00:03:38,000 --> 00:03:41,000
and we are interested in the first two values

67
00:03:41,000 --> 00:03:43,000
which should be the year and the month.

68
00:03:43,000 --> 00:03:45,000
Which is why we convert them to numbers

69
00:03:45,000 --> 00:03:48,000
and then validate them down there.

70
00:03:48,000 --> 00:03:52,000
Now if validation fails, however, we don't wanna return JSX.

71
00:03:52,000 --> 00:03:55,000
That's not possible in getServerSideProps.

72
00:03:56,000 --> 00:03:59,000
We always have to return an object instead.

73
00:03:59,000 --> 00:04:01,000
But if the validation fails,

74
00:04:01,000 --> 00:04:05,000
I don't wanna return a props object here,

75
00:04:05,000 --> 00:04:07,000
or a props key.

76
00:04:07,000 --> 00:04:10,000
Instead, here, I'll then set notFound to true.

77
00:04:10,000 --> 00:04:13,000
I wanna show the 404 page

78
00:04:13,000 --> 00:04:17,000
if an invalid parameter combination is passed in.

79
00:04:18,000 --> 00:04:23,000
We could also consider redirecting to some error page

80
00:04:23,000 --> 00:04:24,000
if we had one.

81
00:04:24,000 --> 00:04:26,000
But here, we don't have one.

82
00:04:26,000 --> 00:04:28,000
We could add one, but I will not do that here.

83
00:04:28,000 --> 00:04:30,000
So I'll comment this out,

84
00:04:30,000 --> 00:04:33,000
and instead show the 404 error page.

85
00:04:33,000 --> 00:04:37,000
Another alternative would be to set some props

86
00:04:37,000 --> 00:04:39,000
like the hasError prop,

87
00:04:39,000 --> 00:04:42,000
and then handle this specific prop

88
00:04:42,000 --> 00:04:46,000
in our component function to show an error message.

89
00:04:46,000 --> 00:04:47,000
And actually,

90
00:04:47,000 --> 00:04:51,000
since we do have that error specific JSX code here,

91
00:04:51,000 --> 00:04:54,000
that might actually be the best alternative.

92
00:04:54,000 --> 00:04:56,000
So it's still worth knowing the other ones,

93
00:04:56,000 --> 00:04:58,000
but I will now not show the 404 page,

94
00:04:58,000 --> 00:05:02,000
but instead return my special hasError prop,

95
00:05:02,000 --> 00:05:05,000
set to true if the validation fails.

96
00:05:06,000 --> 00:05:08,000
So that in the component function,

97
00:05:08,000 --> 00:05:11,000
in this FilteredEventsPage function,

98
00:05:11,000 --> 00:05:14,000
we should expect props, and then down there,

99
00:05:14,000 --> 00:05:18,000
instead of validating our query parameters,

100
00:05:18,000 --> 00:05:22,000
I check if props hasError is true.

101
00:05:22,000 --> 00:05:25,000
And if that's the case, I'll show this error message.

102
00:05:26,000 --> 00:05:29,000
I think that actually makes the most sense,

103
00:05:29,000 --> 00:05:30,000
but you can also go

104
00:05:30,000 --> 00:05:32,000
with one of the two alternatives I showed.

105
00:05:35,000 --> 00:05:37,000
Now if we make it past this if check,

106
00:05:37,000 --> 00:05:40,000
we do have valid parameter values,

107
00:05:40,000 --> 00:05:44,000
and therefore now we wanna get our filtered events.

108
00:05:44,000 --> 00:05:47,000
For this, I'll go to dummy data,

109
00:05:47,000 --> 00:05:51,000
and take this getFilteredEvents function,

110
00:05:51,000 --> 00:05:54,000
and bring that over into api-util.

111
00:05:54,000 --> 00:05:55,000
Maybe down there.

112
00:05:56,000 --> 00:06:01,000
Here, we getFilteredEvents by reaching out to DUMMY_EVENTS

113
00:06:01,000 --> 00:06:03,000
and calling filter on that.

114
00:06:03,000 --> 00:06:06,000
Now just as in the other functions here,

115
00:06:06,000 --> 00:06:09,000
I will instead now turn this into a async function,

116
00:06:09,000 --> 00:06:13,000
then get access to allEvents by awaiting getAllEvents,

117
00:06:15,000 --> 00:06:16,000
and then using allEvents here

118
00:06:16,000 --> 00:06:19,000
instead of DUMMY_EVENTS for filtering.

119
00:06:21,000 --> 00:06:25,000
And with that, back in this slug page,

120
00:06:25,000 --> 00:06:28,000
we now wanna import getFilteredEvents,

121
00:06:28,000 --> 00:06:31,000
not from dummy-data, but from the helpers folder,

122
00:06:31,000 --> 00:06:35,000
and the api-util file.

123
00:06:35,000 --> 00:06:38,000
And then down there in getServerSideProps,

124
00:06:39,000 --> 00:06:41,000
we now get our filtered events

125
00:06:41,000 --> 00:06:44,000
by awaiting getFilteredEvents,

126
00:06:44,000 --> 00:06:48,000
to which we still pass this object with this data.

127
00:06:48,000 --> 00:06:51,000
Because I haven't changed the function's signature

128
00:06:51,000 --> 00:06:52,000
of this function.

129
00:06:52,000 --> 00:06:54,000
It still wants the same parameter.

130
00:06:55,000 --> 00:06:58,000
But we should await because this is now an async function

131
00:06:58,000 --> 00:07:00,000
returning a promise, therefore.

132
00:07:01,000 --> 00:07:03,000
So that gives us our filteredEvents,

133
00:07:03,000 --> 00:07:07,000
and hence, here, through props, we can expose our events,

134
00:07:07,000 --> 00:07:08,000
our filtered events,

135
00:07:08,000 --> 00:07:10,000
through an events prop.

136
00:07:12,000 --> 00:07:15,000
And therefore, back in the component function,

137
00:07:15,000 --> 00:07:17,000
now, in there,

138
00:07:17,000 --> 00:07:22,000
we actually don't really need to parse the URL anymore,

139
00:07:22,000 --> 00:07:25,000
though I'll keep that code around for now.

140
00:07:26,000 --> 00:07:30,000
But I will comment it out like this.

141
00:07:30,000 --> 00:07:34,000
Instead, now we are already using props.hasError,

142
00:07:35,000 --> 00:07:39,000
and I now also in addition wanna set my filteredEvents here

143
00:07:39,000 --> 00:07:41,000
equal to props.events.

144
00:07:41,000 --> 00:07:46,000
So this events prop which we populate in getServerSideProps.

145
00:07:47,000 --> 00:07:49,000
With that, if we save this,

146
00:07:49,000 --> 00:07:53,000
if I reload this page for this kind of filter,

147
00:07:53,000 --> 00:07:56,000
I still get no events found.

148
00:07:56,000 --> 00:08:00,000
Now, if I do pick a combination that exists, though,

149
00:08:00,000 --> 00:08:03,000
I get an error: numYear is not defined.

150
00:08:04,000 --> 00:08:05,000
That makes sense, because now,

151
00:08:05,000 --> 00:08:08,000
in there, I am constructing a date

152
00:08:08,000 --> 00:08:09,000
with numYear and numMonth,

153
00:08:11,000 --> 00:08:13,000
and we're not having that anymore,

154
00:08:13,000 --> 00:08:18,000
because I am not extracting it from the URL anymore.

155
00:08:18,000 --> 00:08:19,000
Now we could do that,

156
00:08:19,000 --> 00:08:23,000
but since we do get it in getServerSideProps anyways,

157
00:08:23,000 --> 00:08:26,000
we can't just expose numYear and month

158
00:08:26,000 --> 00:08:28,000
through props to the component.

159
00:08:28,000 --> 00:08:31,000
So here, besides exposing the events,

160
00:08:31,000 --> 00:08:33,000
I'll also expose my date,

161
00:08:33,000 --> 00:08:38,000
and here I'll then just expose this as a object

162
00:08:38,000 --> 00:08:41,000
where year is set equal to numYear,

163
00:08:41,000 --> 00:08:44,000
and month is set equal to numMonth.

164
00:08:45,000 --> 00:08:48,000
And now that we exposed this date prop,

165
00:08:48,000 --> 00:08:50,000
we can go to the component function,

166
00:08:50,000 --> 00:08:54,000
and build a date by accessing props.date.year,

167
00:08:56,000 --> 00:08:59,000
and then props.date.month.

168
00:08:59,000 --> 00:09:02,000
So these props which we just added.

169
00:09:02,000 --> 00:09:04,000
For that, if we save this and reload,

170
00:09:04,000 --> 00:09:08,000
now this gets loaded correctly.

171
00:09:08,000 --> 00:09:12,000
And this is now pre-rendered on the fly on the server

172
00:09:12,000 --> 00:09:15,000
for every incoming request.

173
00:09:15,000 --> 00:09:19,000
Because we are using getServerSideProps here.

174
00:09:19,000 --> 00:09:21,000
And of course, again, we can see that

175
00:09:21,000 --> 00:09:23,000
if we inspect the page source,

176
00:09:23,000 --> 00:09:28,000
there, the event data is part of that HTML content.

177
00:09:29,000 --> 00:09:33,000
And again, if I use some other filter

178
00:09:33,000 --> 00:09:36,000
where we don't find any events, we see that message.

179
00:09:36,000 --> 00:09:39,000
And if I enter something invalid here,

180
00:09:39,000 --> 00:09:41,000
we see the invalid filter page.

181
00:09:41,000 --> 00:09:45,000
And that also is pre-rendered

182
00:09:45,000 --> 00:09:46,000
as you can see here.

183
00:09:47,000 --> 00:09:49,000
So that's how we can use getServerSideProps.

