1
00:00:02,000 --> 00:00:04,000
So now we also execute server-side code

2
00:00:04,000 --> 00:00:08,000
in getStaticProps and I can't emphasize enough

3
00:00:08,000 --> 00:00:10,000
that this is a standard way of doing it.

4
00:00:10,000 --> 00:00:13,000
This code will not end up in the client-side bundle.

5
00:00:13,000 --> 00:00:15,000
Your credentials will not be exposed,

6
00:00:15,000 --> 00:00:17,000
the bundle will not be bloated.

7
00:00:17,000 --> 00:00:21,000
This code will execute when this page is pre-generated.

8
00:00:22,000 --> 00:00:26,000
Now, for the MeetupDetail page,

9
00:00:26,000 --> 00:00:29,000
we also want to fetch data from the database now

10
00:00:29,000 --> 00:00:33,000
for a specific meetup that was selected

11
00:00:33,000 --> 00:00:37,000
but also for determining which paths should be generated.

12
00:00:37,000 --> 00:00:40,000
So which meetup IDs should be supported

13
00:00:40,000 --> 00:00:41,000
because after all,

14
00:00:41,000 --> 00:00:44,000
we do only have a limited list of meetups

15
00:00:44,000 --> 00:00:47,000
with specific IDs here.

16
00:00:47,000 --> 00:00:49,000
So we wanna pre-generate all the paths

17
00:00:49,000 --> 00:00:51,000
for all those IDs which we have here.

18
00:00:52,000 --> 00:00:54,000
And therefore, we will again need

19
00:00:54,000 --> 00:00:56,000
to connect to MongoDB.

20
00:00:56,000 --> 00:00:58,000
So for this, from index.js,

21
00:00:58,000 --> 00:01:01,000
I will again copy this connection code

22
00:01:01,000 --> 00:01:03,000
and again, you could refactor therefore

23
00:01:03,000 --> 00:01:06,000
if you wanted to avoid duplication.

24
00:01:07,000 --> 00:01:11,000
And I will import MongoClient here

25
00:01:11,000 --> 00:01:15,000
from mongodb like this

26
00:01:15,000 --> 00:01:19,000
in the meetupId index.js file

27
00:01:19,000 --> 00:01:22,000
and then here we can start with getStaticPaths.

28
00:01:23,000 --> 00:01:26,000
In there, I wanna connect to my database

29
00:01:26,000 --> 00:01:28,000
and get access to the meetupsCollection

30
00:01:29,000 --> 00:01:33,000
and then now here I wanna get all the meetup data.

31
00:01:33,000 --> 00:01:36,000
So for this, I get my meetups

32
00:01:36,000 --> 00:01:41,000
by again awaiting meetupsCollection.find.

33
00:01:41,000 --> 00:01:43,000
Find gives me access to all the meetups.

34
00:01:44,000 --> 00:01:48,000
Now, actually here I'm only interested in the IDs

35
00:01:48,000 --> 00:01:50,000
and therefore we can tweak find

36
00:01:50,000 --> 00:01:53,000
and pass an empty object as a first argument.

37
00:01:53,000 --> 00:01:56,000
Here we could define our filter criteria

38
00:01:56,000 --> 00:01:59,000
if we wanna not find all documents

39
00:01:59,000 --> 00:02:02,000
but filter for certain field values.

40
00:02:02,000 --> 00:02:03,000
But I do wanna find all here.

41
00:02:03,000 --> 00:02:06,000
Hence we use a empty object,

42
00:02:06,000 --> 00:02:08,000
which means give me all the objects.

43
00:02:08,000 --> 00:02:11,000
I have no filter criteria

44
00:02:11,000 --> 00:02:14,000
but then we can pass a second argument

45
00:02:14,000 --> 00:02:18,000
where we can define which fields should be extracted

46
00:02:18,000 --> 00:02:19,000
for every document.

47
00:02:19,000 --> 00:02:23,000
And by default, all the fields will be returned.

48
00:02:23,000 --> 00:02:26,000
So all the field values, title, image and so on

49
00:02:26,000 --> 00:02:28,000
but if we're only interested in the ID,

50
00:02:28,000 --> 00:02:32,000
we can also add _id here

51
00:02:32,000 --> 00:02:34,000
and set this to one,

52
00:02:34,000 --> 00:02:37,000
which means only include the ID

53
00:02:37,000 --> 00:02:40,000
but no other field values.

54
00:02:40,000 --> 00:02:42,000
And with that, we're only fetching the IDs.

55
00:02:42,000 --> 00:02:44,000
So we fetch the document objects

56
00:02:44,000 --> 00:02:48,000
but they each will only contain the ID, nothing else.

57
00:02:49,000 --> 00:02:51,000
Now again, we should call toArray here

58
00:02:51,000 --> 00:02:55,000
to convert this to a JavaScript array of objects.

59
00:02:55,000 --> 00:02:57,000
And now we got our meetups here

60
00:02:57,000 --> 00:03:00,000
and now we can generate the paths dynamically.

61
00:03:01,000 --> 00:03:03,000
Instead of hard coding this array,

62
00:03:03,000 --> 00:03:05,000
we can use meetups here

63
00:03:05,000 --> 00:03:08,000
and then map every meetup item,

64
00:03:08,000 --> 00:03:11,000
which is a document with an id

65
00:03:11,000 --> 00:03:16,000
into an object, because paths should be an array of objects,

66
00:03:17,000 --> 00:03:20,000
where every object has this params key

67
00:03:20,000 --> 00:03:22,000
just as we have it down there.

68
00:03:22,000 --> 00:03:24,000
And then we have a nested object in there

69
00:03:24,000 --> 00:03:27,000
where we define our meetupId values.

70
00:03:27,000 --> 00:03:32,000
And the values for meetupId should now be our IDs here.

71
00:03:33,000 --> 00:03:36,000
So here we can then access meetup,

72
00:03:36,000 --> 00:03:40,000
so this parameter, which map gives us automatically,

73
00:03:40,000 --> 00:03:42,000
._id.toString, like that.

74
00:03:47,000 --> 00:03:49,000
And now get rid of this array here.

75
00:03:51,000 --> 00:03:56,000
With that, we're generating our array of paths dynamically.

76
00:03:56,000 --> 00:03:59,000
And as a result, if I now save this,

77
00:03:59,000 --> 00:04:00,000
if we reload the starting page,

78
00:04:00,000 --> 00:04:02,000
if we click on Show Details,

79
00:04:02,000 --> 00:04:05,000
we're taken to the page for this specific object,

80
00:04:05,000 --> 00:04:07,000
for this specific meetup.

81
00:04:07,000 --> 00:04:09,000
And you'll see this cryptic ID here,

82
00:04:09,000 --> 00:04:14,000
which is this autogenerated ID MongoDB generated for us.

83
00:04:15,000 --> 00:04:17,000
So that's working.

84
00:04:17,000 --> 00:04:21,000
But we're not yet fetching the data dynamically here.

85
00:04:21,000 --> 00:04:23,000
I wanna do that as well.

86
00:04:23,000 --> 00:04:24,000
For this, first of all,

87
00:04:24,000 --> 00:04:27,000
I'll close the connection here.

88
00:04:27,000 --> 00:04:30,000
It isn't a bad idea to do that once we're done

89
00:04:30,000 --> 00:04:32,000
and then I'll copy this code

90
00:04:32,000 --> 00:04:35,000
from getStaticPaths and add it here

91
00:04:36,000 --> 00:04:39,000
after we got the meetupId instead of logging the ID.

92
00:04:40,000 --> 00:04:43,000
I'll again connect and get access to the collection.

93
00:04:43,000 --> 00:04:45,000
Again, we could outsource this into a function

94
00:04:45,000 --> 00:04:47,000
if we wanted to.

95
00:04:47,000 --> 00:04:50,000
And then here, I want to get access to a single meetup,

96
00:04:50,000 --> 00:04:54,000
not to all the meetups, just a single meetup.

97
00:04:54,000 --> 00:04:56,000
So I want to get access to my selectedMeetup here

98
00:04:56,000 --> 00:04:59,000
and we do this by using the meetupsCollection

99
00:04:59,000 --> 00:05:02,000
and then using the the findOne method.

100
00:05:03,000 --> 00:05:07,000
findOne finds one single document.

101
00:05:07,000 --> 00:05:10,000
And to findOne, we need to pass an object

102
00:05:10,000 --> 00:05:13,000
where we define how to filter,

103
00:05:13,000 --> 00:05:16,000
how to search for that document.

104
00:05:16,000 --> 00:05:19,000
On this object, you can pass your field names,

105
00:05:19,000 --> 00:05:23,000
like title, image, address or description as keys

106
00:05:23,000 --> 00:05:27,000
and then the values for which you wanna search as values.

107
00:05:27,000 --> 00:05:31,000
So we could pass title: A First Meetup as a key-value pair

108
00:05:31,000 --> 00:05:33,000
into this object here

109
00:05:33,000 --> 00:05:38,000
to find this first meetup where the title is A First Meetup.

110
00:05:39,000 --> 00:05:41,000
Now, here we don't wanna search by title

111
00:05:41,000 --> 00:05:42,000
but instead by ID.

112
00:05:42,000 --> 00:05:45,000
So I wanna make sure that _id,

113
00:05:45,000 --> 00:05:49,000
the automatically added and generated ID field,

114
00:05:49,000 --> 00:05:54,000
has a value of meetupId, so this meetupId,

115
00:05:54,000 --> 00:05:56,000
which we extract from the params up there.

116
00:05:57,000 --> 00:06:00,000
This then finds us this single meetup.

117
00:06:00,000 --> 00:06:03,000
This returns a promise because it's an asynchronous task

118
00:06:03,000 --> 00:06:05,000
and hence we should await this

119
00:06:05,000 --> 00:06:09,000
and make sure that we added async in front of the function.

120
00:06:09,000 --> 00:06:12,000
Oops, and with that we got the selectedMeetup eventually.

121
00:06:14,000 --> 00:06:16,000
And now it's the selectedMeetup,

122
00:06:16,000 --> 00:06:19,000
which I return here as meetupData, like this.

123
00:06:22,000 --> 00:06:25,000
And then if we do that and save everything,

124
00:06:25,000 --> 00:06:28,000
if I reload this meetup here,

125
00:06:28,000 --> 00:06:29,000
it should load successfully

126
00:06:29,000 --> 00:06:31,000
and it should display all the data.

127
00:06:31,000 --> 00:06:34,000
Now, at the moment, the data I'm showing here, however,

128
00:06:34,000 --> 00:06:37,000
is still hard coded in the JSX code

129
00:06:37,000 --> 00:06:40,000
and now it's finally time to use our props data here.

130
00:06:40,000 --> 00:06:44,000
So the actual fetch data in the JSX code as well.

131
00:06:44,000 --> 00:06:47,000
For this, we're exposing the meetupData prop

132
00:06:47,000 --> 00:06:50,000
to the component and hence, here we should accept props

133
00:06:50,000 --> 00:06:52,000
and use that data here.

134
00:06:52,000 --> 00:06:57,000
So that for image, I'm passing in props.image

135
00:06:58,000 --> 00:07:03,000
and for the title, we pass in props.title and so on.

136
00:07:04,000 --> 00:07:05,000
Same for the address.

137
00:07:05,000 --> 00:07:08,000
That's props.address.

138
00:07:08,000 --> 00:07:11,000
And for description, it's props.description.

139
00:07:13,000 --> 00:07:16,000
And actually not props dot but props.meetupData dot

140
00:07:19,000 --> 00:07:22,000
because we have that meetupData prop,

141
00:07:22,000 --> 00:07:26,000
this prop which holds the meetup item, the meetup object.

142
00:07:26,000 --> 00:07:30,000
So we need to drill into that meetupData object first

143
00:07:30,000 --> 00:07:34,000
before we can access image, title, address and description.

144
00:07:34,000 --> 00:07:36,000
Now, once we did all of that,

145
00:07:36,000 --> 00:07:38,000
there's one other thing we need to do though,

146
00:07:38,000 --> 00:07:39,000
which I just noticed.

147
00:07:39,000 --> 00:07:42,000
Here for findOne, I'm looking for an id,

148
00:07:42,000 --> 00:07:44,000
which is equal to the id I'm getting out

149
00:07:44,000 --> 00:07:48,000
of my URL but that, of course, will be a string.

150
00:07:48,000 --> 00:07:51,000
Keep in mind that in MongoDB actually,

151
00:07:51,000 --> 00:07:55,000
our IDs are these strange object ID things.

152
00:07:55,000 --> 00:07:59,000
To ensure that we can correctly look for a specific ID,

153
00:07:59,000 --> 00:08:01,000
we need to convert it from string

154
00:08:01,000 --> 00:08:03,000
to such a object ID thing

155
00:08:03,000 --> 00:08:05,000
and for this, from MongoDB,

156
00:08:05,000 --> 00:08:09,000
you should import ObjectId like this

157
00:08:09,000 --> 00:08:12,000
with a lowercase D at the end.

158
00:08:12,000 --> 00:08:14,000
And wrap your string with that.

159
00:08:14,000 --> 00:08:19,000
So down here, wrap ObjectId around meetupId

160
00:08:19,000 --> 00:08:21,000
and this will convert this string

161
00:08:21,000 --> 00:08:23,000
into such a ObjectId object.

162
00:08:23,000 --> 00:08:25,000
And once that is done,

163
00:08:25,000 --> 00:08:28,000
we also wanna go to selectedMeetup

164
00:08:28,000 --> 00:08:31,000
and make sure that there we convert this id,

165
00:08:31,000 --> 00:08:35,000
this _id field back to a string

166
00:08:35,000 --> 00:08:38,000
because otherwise, we'll get that serialization error

167
00:08:38,000 --> 00:08:39,000
we saw before.

168
00:08:40,000 --> 00:08:44,000
So for this, I'll set meetupData actually to an object

169
00:08:44,000 --> 00:08:46,000
where I do add an id field,

170
00:08:46,000 --> 00:08:48,000
which is equal to selectedMeetup._id.toString

171
00:08:52,000 --> 00:08:53,000
and where I then add all the other data,

172
00:08:53,000 --> 00:08:56,000
like selectedMeetup.title,

173
00:08:56,000 --> 00:09:00,000
then the address, which is selectedMeetup.address.

174
00:09:00,000 --> 00:09:04,000
Then the image, which is selectedMeetup.image

175
00:09:04,000 --> 00:09:06,000
and then also last but not least,

176
00:09:06,000 --> 00:09:09,000
the description, which is selectedMeetup.description.

177
00:09:12,000 --> 00:09:15,000
And with all that done, if we now save this,

178
00:09:15,000 --> 00:09:17,000
if you reload a single meetup page,

179
00:09:17,000 --> 00:09:20,000
you see the data for that single meetup.

180
00:09:20,000 --> 00:09:24,000
And that works for all the meetups now.

181
00:09:24,000 --> 00:09:26,000
And now these meetup detail pages

182
00:09:26,000 --> 00:09:30,000
are pre-rendered on the server dynamically

183
00:09:30,000 --> 00:09:33,000
with our code being active

184
00:09:33,000 --> 00:09:37,000
and with our code establishing that database connection

185
00:09:37,000 --> 00:09:39,000
and fetching the data from there.

