1
00:00:01,500 --> 00:00:04,382
Now our post model is taking shape

2
00:00:04,382 --> 00:00:06,739
and it's able to save a new post,

3
00:00:06,739 --> 00:00:10,184
update an existing post, and delete a post.

4
00:00:10,184 --> 00:00:13,890
There are two functionalities that are missing,

5
00:00:13,890 --> 00:00:16,409
which we absolutely also need to add.

6
00:00:16,409 --> 00:00:20,351
And that's the functionality to fetch a list of posts

7
00:00:20,351 --> 00:00:25,351
and the functionality to get a single post in the end.

8
00:00:25,485 --> 00:00:29,645
Now let's start with fetching a list of posts.

9
00:00:29,645 --> 00:00:34,285
What we can do for that is we can add another method.

10
00:00:34,285 --> 00:00:36,333
But now, the trick is

11
00:00:36,333 --> 00:00:41,333
that we will actually not instantiate this post-class

12
00:00:41,980 --> 00:00:43,928
before we wanna call this method.

13
00:00:43,928 --> 00:00:48,400
Because whilst it made sense to call save and delete

14
00:00:48,400 --> 00:00:52,648
on an instantiated post, so on our concrete post object,

15
00:00:52,648 --> 00:00:55,512
if we're about to fetch a list of post objects,

16
00:00:55,512 --> 00:00:58,890
we have no single post object yet.

17
00:00:58,890 --> 00:01:00,471
And to make this work,

18
00:01:00,471 --> 00:01:03,479
JavaScript classes have another feature

19
00:01:03,479 --> 00:01:06,759
which is called static methods.

20
00:01:06,759 --> 00:01:11,303
You can add a method, like fetchAll, for example,

21
00:01:11,303 --> 00:01:14,167
and add the static keyword in front of that.

22
00:01:14,167 --> 00:01:18,380
The special thing about static methods is

23
00:01:18,380 --> 00:01:21,159
that you don't call them on the instantiated object,

24
00:01:21,159 --> 00:01:24,738
so on the object that's based on the class,

25
00:01:24,738 --> 00:01:26,877
but instead on the class itself.

26
00:01:26,877 --> 00:01:31,117
And we can also turn this into an async method like this.

27
00:01:31,117 --> 00:01:35,933
So back in blog.js, where I now do need all my posts,

28
00:01:35,933 --> 00:01:39,213
which would be for the admin page here.

29
00:01:39,213 --> 00:01:41,853
There, I'm fetching all my posts.

30
00:01:41,853 --> 00:01:46,046
We can now copy this line of code here,

31
00:01:46,046 --> 00:01:49,749
go back to post.js, and add it in there.

32
00:01:49,749 --> 00:01:54,749
And then, here we can just return all those posts like that.

33
00:01:57,020 --> 00:01:59,170
Now back in blog.js, again,

34
00:01:59,170 --> 00:02:04,170
this means that we can get all the posts by calling Post,

35
00:02:04,512 --> 00:02:06,902
so using the class which we created,

36
00:02:06,902 --> 00:02:09,470
and which we are importing under that name

37
00:02:09,470 --> 00:02:12,848
in this blog.js file, .fetchAll.

38
00:02:12,848 --> 00:02:16,169
And that's the difference to save and delete.

39
00:02:16,169 --> 00:02:21,169
We called save and delete on existing posts objects,

40
00:02:21,740 --> 00:02:24,989
like here in line 116, in my case.

41
00:02:24,989 --> 00:02:28,170
We first created the post and then called save

42
00:02:28,170 --> 00:02:29,707
on that created post.

43
00:02:29,707 --> 00:02:32,199
Now, we're not doing that.

44
00:02:32,199 --> 00:02:34,497
Instead, we're calling fetchAll directly

45
00:02:34,497 --> 00:02:36,964
on the class itself.

46
00:02:36,964 --> 00:02:39,408
So I can await this here,

47
00:02:39,408 --> 00:02:42,591
and then I will still have my posts.

48
00:02:42,591 --> 00:02:46,204
But the logic for fetching to posts now resides

49
00:02:46,204 --> 00:02:47,810
in a different place.

50
00:02:47,810 --> 00:02:49,985
It now resides inside of our model

51
00:02:49,985 --> 00:02:52,287
with the help of such a static method.

52
00:02:52,287 --> 00:02:55,600
And that's why static methods,

53
00:02:55,600 --> 00:02:58,240
a new feature which we haven't learned about before,

54
00:02:58,240 --> 00:03:01,526
can also be very helpful if you wanna use a class,

55
00:03:01,526 --> 00:03:03,628
not just as a blueprint,

56
00:03:03,628 --> 00:03:08,290
but also for grouping related functionalities together.

57
00:03:08,290 --> 00:03:10,840
Because that's what we're doing here in the end.

58
00:03:10,840 --> 00:03:13,892
We're grouping all the posts-related functionalities

59
00:03:13,892 --> 00:03:16,327
together into one class.

60
00:03:16,327 --> 00:03:18,924
And with the help of static methods,

61
00:03:18,924 --> 00:03:21,761
we can also include functionalities that don't act

62
00:03:21,761 --> 00:03:24,700
on a single post that already exists,

63
00:03:24,700 --> 00:03:29,700
but that are instead only generally related to posts

64
00:03:29,770 --> 00:03:31,483
and working with posts.

65
00:03:32,907 --> 00:03:36,530
Now, just as I have the static fetchAll method

66
00:03:36,530 --> 00:03:37,895
for fetching all posts,

67
00:03:37,895 --> 00:03:40,429
we can, therefore, also add another static method

68
00:03:40,429 --> 00:03:44,060
for fetching a single post by its ID.

69
00:03:44,060 --> 00:03:47,670
Though here, for a single post, we could, of course,

70
00:03:47,670 --> 00:03:51,180
argue that we instead create a fetch function,

71
00:03:51,180 --> 00:03:53,841
a fetch method like this, which is not static,

72
00:03:53,841 --> 00:03:57,820
where just as with deleting,

73
00:03:57,820 --> 00:04:01,523
we check if we have an ID, and if we don't, we just return.

74
00:04:01,523 --> 00:04:06,523
Because we need that ID to then populate this post object,

75
00:04:08,006 --> 00:04:11,270
which we created with the data that was fetched

76
00:04:11,270 --> 00:04:12,103
from the database.

77
00:04:12,103 --> 00:04:14,635
So that means that in blog.js,

78
00:04:14,635 --> 00:04:18,016
where I am fetching the data for a single post,

79
00:04:18,016 --> 00:04:19,454
here in this get route,

80
00:04:19,454 --> 00:04:23,019
I am copying, or cutting, this logic,

81
00:04:23,019 --> 00:04:28,019
and I will execute this here in my post model now.

82
00:04:28,080 --> 00:04:31,540
And that is my post, which I get here.

83
00:04:31,540 --> 00:04:36,540
And now I can set this .title,

84
00:04:36,970 --> 00:04:40,220
so of this class or of the object that was created based

85
00:04:40,220 --> 00:04:43,550
on this class equal to post.title,

86
00:04:43,550 --> 00:04:45,892
so equal to the title I fetched from the database.

87
00:04:45,892 --> 00:04:47,395
And just to make this clear,

88
00:04:47,395 --> 00:04:49,730
this is, again, my postDocument.

89
00:04:49,730 --> 00:04:52,527
So we can use that to clarify that here I got

90
00:04:52,527 --> 00:04:55,275
back my document from the database.

91
00:04:55,275 --> 00:05:00,275
And I set this content equal to postDocument.content.

92
00:05:02,410 --> 00:05:06,717
And then, we could call the fetch method on a post

93
00:05:06,717 --> 00:05:09,590
that we instantiated with an ID,

94
00:05:09,590 --> 00:05:11,670
but without a title or content,

95
00:05:11,670 --> 00:05:14,423
because we're setting this dynamically in here then.

96
00:05:15,323 --> 00:05:18,237
So then, in blog.js, here,

97
00:05:18,237 --> 00:05:22,143
we could again create a post by calling new Post.

98
00:05:23,200 --> 00:05:25,284
We don't need to create the post ID here.

99
00:05:25,284 --> 00:05:28,641
Instead, we pass null for the title of the content,

100
00:05:28,641 --> 00:05:31,623
and we pass req.params.id for the ID.

101
00:05:31,623 --> 00:05:36,330
And then, we call post.fetch here

102
00:05:36,330 --> 00:05:38,360
to trigger that fetch function we just added

103
00:05:38,360 --> 00:05:41,386
to use that internally-stored ID

104
00:05:41,386 --> 00:05:45,084
to fetch all the other data that belongs to this post.

105
00:05:45,084 --> 00:05:50,084
Now, I will await that, and then thereafter, we continue.

106
00:05:51,404 --> 00:05:55,310
Now this check here won't do the trick anymore though,

107
00:05:55,310 --> 00:05:58,279
because now post will always exist,

108
00:05:58,279 --> 00:06:00,890
but that doesn't necessarily tell us

109
00:06:00,890 --> 00:06:03,453
whether fetching the data will succeed.

110
00:06:03,453 --> 00:06:06,037
That's not too problematic though,

111
00:06:06,037 --> 00:06:08,355
because this check your wasn't

112
00:06:08,355 --> 00:06:11,450
entirely correct anymore anyways.

113
00:06:11,450 --> 00:06:12,320
Therefore, here,

114
00:06:12,320 --> 00:06:13,930
we wanna update this check

115
00:06:13,930 --> 00:06:17,450
and maybe check if post.title is not set,

116
00:06:17,450 --> 00:06:20,080
or if not post.content,

117
00:06:20,080 --> 00:06:23,098
which means we created a post object,

118
00:06:23,098 --> 00:06:26,710
but we were not able to populate that

119
00:06:26,710 --> 00:06:28,240
with title and content.

120
00:06:28,240 --> 00:06:30,160
And there would be other ways

121
00:06:30,160 --> 00:06:32,842
of implementing this logic as well,

122
00:06:32,842 --> 00:06:35,303
but this should do the trick.

123
00:06:36,234 --> 00:06:38,680
And with all of that,

124
00:06:38,680 --> 00:06:43,321
we now outsourced all our post data-related logic

125
00:06:43,321 --> 00:06:46,725
into the post model, as it should be.

126
00:06:46,725 --> 00:06:51,725
Now in blog.js, we can get rid of that import to db,

127
00:06:52,016 --> 00:06:54,893
and we can get rid of the objectId creation here

128
00:06:54,893 --> 00:06:56,928
and of the MongoDB import.

129
00:06:56,928 --> 00:07:01,003
Because that is now all taking place in the post model file.

130
00:07:01,003 --> 00:07:04,443
And that's the idea behind the post model file.

131
00:07:05,415 --> 00:07:08,320
Now if I save this, this crashes.

132
00:07:08,320 --> 00:07:09,853
Let's see what's wrong.

133
00:07:10,970 --> 00:07:11,803
My mistake.

134
00:07:11,803 --> 00:07:14,898
When you add a static method, that should be async.

135
00:07:14,898 --> 00:07:17,542
async has to come after static.

136
00:07:17,542 --> 00:07:21,960
So it's static async instead of async static.

137
00:07:21,960 --> 00:07:23,253
We have to swap that.

138
00:07:24,620 --> 00:07:25,963
So it's static async.

139
00:07:25,963 --> 00:07:29,513
And with that, if we now reload, that's looking good.

140
00:07:29,513 --> 00:07:30,987
If I visit the admin page,

141
00:07:30,987 --> 00:07:35,269
all the posts are still fetched without new errors.

142
00:07:35,269 --> 00:07:36,683
So that's working.

143
00:07:36,683 --> 00:07:40,427
And if we view a single post, that fails though,

144
00:07:40,427 --> 00:07:45,427
and that fails because postId is not defined.

145
00:07:45,640 --> 00:07:47,644
And that's just a mistake from my side again,

146
00:07:47,644 --> 00:07:50,222
here in the post model, when we fetch.

147
00:07:50,222 --> 00:07:52,146
Of course, when I find a post,

148
00:07:52,146 --> 00:07:54,647
this should not look for postId.

149
00:07:54,647 --> 00:07:56,370
This doesn't exist here.

150
00:07:56,370 --> 00:07:58,672
Instead, we wanna use this ID here.

151
00:07:58,672 --> 00:08:01,849
So same mistake as before, sorry.

152
00:08:01,849 --> 00:08:05,430
But that is also, I guess, a bit helpful

153
00:08:05,430 --> 00:08:08,010
because you see that such errors are happening.

154
00:08:08,010 --> 00:08:09,813
It's easy to overlook something like this,

155
00:08:09,813 --> 00:08:12,390
and it's always the error messages,

156
00:08:12,390 --> 00:08:13,930
which you wanna have a look at

157
00:08:13,930 --> 00:08:16,515
to see why things are failing.

158
00:08:16,515 --> 00:08:19,715
With that added though, if I now reload,

159
00:08:19,715 --> 00:08:22,293
populating this forum works correctly again.

160
00:08:22,293 --> 00:08:24,776
So therefore, now that is working.

161
00:08:24,776 --> 00:08:28,834
Now there is one change we have to implement though,

162
00:08:28,834 --> 00:08:33,833
and that is related to how we are fetching a single post.

163
00:08:33,898 --> 00:08:38,070
We are now doing that with help of this fetch method,

164
00:08:38,070 --> 00:08:38,929
which we added,

165
00:08:38,929 --> 00:08:43,241
which populates the existing post object with the data.

166
00:08:43,241 --> 00:08:45,887
Now there is a subtle issue with that,

167
00:08:45,887 --> 00:08:47,737
which can be really hard to spot.

168
00:08:47,737 --> 00:08:52,737
When we rely on this post object based on our post class,

169
00:08:53,017 --> 00:08:56,870
then the ID of the post is stored

170
00:08:56,870 --> 00:09:00,791
in an ID property, not _id.

171
00:09:00,791 --> 00:09:05,372
The implication of that is that in all the places

172
00:09:05,372 --> 00:09:08,895
where we rely on our own post object

173
00:09:08,895 --> 00:09:12,388
instead of that document fetched from the database,

174
00:09:12,388 --> 00:09:16,392
we now must not work with _id anymore,

175
00:09:16,392 --> 00:09:18,164
but with just ID.

176
00:09:18,164 --> 00:09:22,985
And in detail, that's the case in our single-post EJS file.

177
00:09:22,985 --> 00:09:27,213
Here, I'm configuring the submit URL

178
00:09:27,213 --> 00:09:30,601
for my updating post route.

179
00:09:30,601 --> 00:09:33,713
And there, I'm accessing post._id.

180
00:09:34,929 --> 00:09:35,779
Now keep in mind

181
00:09:35,779 --> 00:09:40,450
that the single-post EJS file is actually rendered

182
00:09:40,450 --> 00:09:42,879
in this get /posts/:id/edit route.

183
00:09:42,879 --> 00:09:47,879
And there, I populate post with that post I created here.

184
00:09:49,460 --> 00:09:52,256
So with my own object based on my own class.

185
00:09:52,256 --> 00:09:56,627
And therefore, the ID in my own object is not stored

186
00:09:56,627 --> 00:10:01,094
in a ._id field, but in just a .id.

187
00:10:01,094 --> 00:10:06,094
So in single-post.ejs, we have to work with just id here.

188
00:10:06,292 --> 00:10:08,540
Otherwise, we would get an error

189
00:10:08,540 --> 00:10:10,853
if we do try to update a post.

190
00:10:12,545 --> 00:10:14,918
This does not affect any other pages

191
00:10:14,918 --> 00:10:16,902
because in no other pages,

192
00:10:16,902 --> 00:10:21,780
we send our own class-based object into the view.

193
00:10:21,780 --> 00:10:23,390
But here we are doing it,

194
00:10:23,390 --> 00:10:26,310
and therefore we need to ensure that we update this

195
00:10:26,310 --> 00:10:28,332
so that when we reload this detail page,

196
00:10:28,332 --> 00:10:33,332
and I do update this post here, saving this works.

197
00:10:34,016 --> 00:10:36,198
Otherwise, it would have failed.

198
00:10:36,198 --> 00:10:37,744
But that's the only thing.

199
00:10:37,744 --> 00:10:42,218
A new post can be created without issues

200
00:10:42,218 --> 00:10:47,218
because there we're not using any ID of any existing object.

201
00:10:47,430 --> 00:10:50,037
But it was important for updating.

202
00:10:50,037 --> 00:10:50,891
And with that,

203
00:10:50,891 --> 00:10:55,663
we now switched to using a model for our posts.

204
00:10:57,070 --> 00:11:01,620
We can do the same for the auth part here,

205
00:11:01,620 --> 00:11:02,992
but I will do that later.

206
00:11:02,992 --> 00:11:06,694
Instead, let's now first move on to the controller part

207
00:11:06,694 --> 00:11:08,669
and see how we implement that

208
00:11:08,669 --> 00:11:11,792
and which other refactorings we can apply

209
00:11:11,792 --> 00:11:14,343
to our post-related routes.

