1
00:00:02,160 --> 00:00:03,860
Now to come to an end,

2
00:00:03,930 --> 00:00:07,520
I now also want to add a little database to this whole thing

3
00:00:07,560 --> 00:00:12,900
so that we don't store the data just in our in-memory storage which will be lost whenever we restart

4
00:00:12,930 --> 00:00:18,930
the server or when we're running out of memory and our server needs to free up some memory, instead

5
00:00:18,930 --> 00:00:25,440
I now want to use a real database and of course you can spend hours or a complete course on just databases

6
00:00:25,620 --> 00:00:30,090
and indeed I have a complete guide on MongoDB which is a database

7
00:00:30,240 --> 00:00:34,680
in case you're interested in that as well besides my Node.js course. So definitely check out these two

8
00:00:34,680 --> 00:00:40,530
courses if you want to learn more about Node.js or MongoDB which is a very popular database engine

9
00:00:40,830 --> 00:00:44,540
that works together with Node.js as particularly well

10
00:00:44,880 --> 00:00:48,220
and indeed it's this MongoDB thing which we will try out now.

11
00:00:48,300 --> 00:00:53,970
You can visit mongodb.com to learn more about it and get started and what we will use here is

12
00:00:53,970 --> 00:01:00,360
a cloud service they offer so that we don't have to install and administer a local database which is

13
00:01:00,360 --> 00:01:04,720
a lot of work. For that you should sign in here or try free to create an account,

14
00:01:04,830 --> 00:01:06,020
it doesn't cost you anything,

15
00:01:06,030 --> 00:01:07,930
you just need to create an account here

16
00:01:08,040 --> 00:01:13,770
and once you did create such an account and you did sign in, you will either end up on a screen like this

17
00:01:13,860 --> 00:01:17,490
or on a welcome screen where you can build your own new cluster.

18
00:01:17,490 --> 00:01:24,240
You can simply walk through all that cluster configuration then and pick the AWS option here, pick

19
00:01:24,240 --> 00:01:28,920
something where you see free tier available so that it doesn't cost you anything to get started,

20
00:01:28,980 --> 00:01:34,400
leave all the other default settings here but double check down there for the cluster here that you're

21
00:01:34,410 --> 00:01:38,530
going with one which is free tier eligible,

22
00:01:38,670 --> 00:01:44,100
that would be this M0 sandbox which I can't choose here because I already created a cluster based on that,

23
00:01:44,100 --> 00:01:47,540
you should be able to choose that and then leave all the other settings,

24
00:01:47,640 --> 00:01:50,150
give it any name you want and create that cluster.

25
00:01:50,140 --> 00:01:51,630
Now I already did that here,

26
00:01:51,630 --> 00:01:56,090
I do have such a cluster here and this is just a cluster for multiple databases

27
00:01:56,130 --> 00:02:02,710
you can add. Now click on connect thereafter to learn how you can connect and there on connect your application

28
00:02:02,710 --> 00:02:06,370
and there, this URL will become important later.

29
00:02:06,400 --> 00:02:14,290
Now actually before we do that however, go to database access and there you can create a new user with

30
00:02:14,290 --> 00:02:21,390
any password of your choice which needs to have at least read and write access to your database. Also

31
00:02:21,420 --> 00:02:25,450
go to network access and there under IP whitelist,

32
00:02:25,510 --> 00:02:30,670
 click on add IP address and make sure you add your local IP address, you should see this option here

33
00:02:30,790 --> 00:02:33,090
if you haven't added it already as I did,

34
00:02:33,130 --> 00:02:37,780
so your local IP address should be added here. With that you can go back to clusters

35
00:02:37,900 --> 00:02:44,710
and now we can connect our application to this. The question of course is, how do we now use this URL

36
00:02:44,760 --> 00:02:51,520
here? How do we now connect to this database? And for that you can search for Node.js MongoDB driver

37
00:02:51,910 --> 00:02:56,950
and you should find this page here, where you can learn more about the MongoDB driver which

38
00:02:56,950 --> 00:03:02,440
is simply a third-party package for Node.js that makes working with MongoDB and sending requests

39
00:03:02,470 --> 00:03:08,670
to it very easy. You just need to run this command here, npm install mongodb --save,

40
00:03:08,860 --> 00:03:14,890
so let's do that in our Node.js application, not on the frontend, you won't communicate directly to

41
00:03:14,890 --> 00:03:15,910
the database from there,

42
00:03:15,970 --> 00:03:17,970
we do that from our backend

43
00:03:18,040 --> 00:03:21,490
and with that done, we can start using that driver.

44
00:03:21,540 --> 00:03:26,590
Now of course you can learn all about the driver here in the documentation here, by clicking on reference

45
00:03:26,590 --> 00:03:31,410
here for example, you can learn more about installing the driver and how to use it

46
00:03:31,540 --> 00:03:37,270
and we're interested in the CRUD operations, which stands for Create Read Update and Delete because we

47
00:03:37,270 --> 00:03:40,120
want to add data, we want to read data,

48
00:03:40,120 --> 00:03:41,940
these are two things we want to do here.

49
00:03:41,950 --> 00:03:45,950
Again if you want to learn more about MongoDB and Node.js and how they work together,

50
00:03:45,970 --> 00:03:52,750
my Node.js course and my MongoDB course are great to dive in because in both I cover MongoDB

51
00:03:52,750 --> 00:03:54,340
and in both

52
00:03:54,340 --> 00:04:00,240
I also cover a bit of Node.js of course with the different focuses depending on the course title.

53
00:04:00,250 --> 00:04:02,740
Now here you see quite good examples though,

54
00:04:02,770 --> 00:04:08,260
for example for how you add something to the database and therefore we'll build up on that.

55
00:04:08,350 --> 00:04:14,650
It all starts by importing this Mongo client, so let's copy that code, go to our location.js file in

56
00:04:14,650 --> 00:04:23,340
the routers folder and import this here and then we want to perform in such an insert operation when we

57
00:04:23,340 --> 00:04:24,940
get a new location.

58
00:04:24,960 --> 00:04:32,900
Now we need our connection URL, so we can copy that and set this up globally here in location.js

59
00:04:32,900 --> 00:04:36,050
as well outside of our middleware functions

60
00:04:36,160 --> 00:04:42,520
and this URL here of course should be the URL you find on your cluster, so you can just copy

61
00:04:42,520 --> 00:04:49,470
that URL and enter this here and now replace user name with the name of the user you created and

62
00:04:49,480 --> 00:04:51,100
the password as well,

63
00:04:51,100 --> 00:04:59,180
so in my case I'm working with Maximilian as a user here and I am using a password which by the time

64
00:04:59,180 --> 00:05:04,720
you're watching this of course will have been changed already. Now in this connection string here, this

65
00:05:04,780 --> 00:05:09,570
/test thing, that's the database you want to connect to and you can specify any name you want here,

66
00:05:09,610 --> 00:05:14,670
if it doesn't exist yet it will be created on the fly and I'll name it locations and you'll leave to

67
00:05:14,670 --> 00:05:20,870
the rest as it is. Now back to this CRUD operations description here,

68
00:05:21,060 --> 00:05:27,450
now we need to create a Mongo client here based on this Mongo client we're importing and we can just

69
00:05:27,450 --> 00:05:34,490
call client like this and pass in this connection URL and then we need to call client connect,

70
00:05:34,750 --> 00:05:39,740
use this callback function which we pass to it and inside of that callback function where we get access

71
00:05:39,740 --> 00:05:46,640
to the connected client, we can then use that client to run queries against it. So we can copy this here,

72
00:05:47,360 --> 00:05:57,440
this entire code and move that into our post route here, using this client here with that callback

73
00:05:57,440 --> 00:05:59,720
function, remove these assert statements,

74
00:05:59,720 --> 00:06:01,080
we don't need to do that here,

75
00:06:01,100 --> 00:06:03,300
you can remove the console logs here,

76
00:06:03,390 --> 00:06:09,780
we should leave that line here where we get access to the database which we connected to on this client

77
00:06:10,380 --> 00:06:15,450
and then MongoDB works with so-called collections and documents.

78
00:06:15,450 --> 00:06:21,660
You have a collection which is like a table of records and you have a document which is like a simple

79
00:06:21,720 --> 00:06:23,790
row in that table.

80
00:06:23,850 --> 00:06:30,330
So we have a collection here which I'll name user locations, user-locations and with insert one.

81
00:06:30,330 --> 00:06:32,750
you can insert one new document there,

82
00:06:32,830 --> 00:06:39,630
the document I want to insert here should have the same format as what I inserted here in my local memory

83
00:06:39,630 --> 00:06:40,380
storage.

84
00:06:40,410 --> 00:06:44,980
We can comment out this code now but I copied the object structure first,

85
00:06:45,000 --> 00:06:49,260
the one thing that differs is the ID. You don't need to add an ID field anymore,

86
00:06:49,290 --> 00:06:52,980
MongoDB will create an ID for you automatically.

87
00:06:52,980 --> 00:06:55,310
Now insert one does not just take this argument,

88
00:06:55,320 --> 00:07:00,090
it also takes a function which will fire as soon as it is done with this operation,

89
00:07:00,090 --> 00:07:07,140
this gives you either an error or the result of that operation and here we can get rid of this

90
00:07:07,140 --> 00:07:10,440
other dummy code with insert many, we don't do that here.

91
00:07:10,620 --> 00:07:11,610
So we're good like that,

92
00:07:11,610 --> 00:07:16,650
we now just want to make sure that here in this function which fires once we're done inserting this,

93
00:07:17,040 --> 00:07:18,680
we send back our response.

94
00:07:18,690 --> 00:07:24,870
So we grab this response code and only send this once this function executes again for all these asynchronous

95
00:07:24,870 --> 00:07:28,520
code logic where this will run at a later point of time

96
00:07:28,530 --> 00:07:31,040
basically once this operation completed.

97
00:07:31,170 --> 00:07:35,520
Now theoretically, we should also check for errors here and send back a different response if we got

98
00:07:35,520 --> 00:07:36,150
one

99
00:07:36,150 --> 00:07:41,280
but to save some time here and not make this overly complicated, for now we'll just assume that this

100
00:07:41,280 --> 00:07:42,120
always works,

101
00:07:42,180 --> 00:07:47,420
again more detailed error handling and so on is covered in the dedicated courses.

102
00:07:47,520 --> 00:07:49,620
So now here we're storing this,

103
00:07:49,620 --> 00:07:54,060
the ID I want to send back has to be retrieved from that result we get here

104
00:07:54,060 --> 00:07:54,630
however.

105
00:07:54,840 --> 00:08:02,550
So for that let's console log r so that we see what's in there when we store something and with that,

106
00:08:02,870 --> 00:08:07,220
let's restart our node application here and let's give this a try.

107
00:08:08,140 --> 00:08:12,370
When we find a place here, that's generally looking good

108
00:08:12,370 --> 00:08:14,240
okay now we got an error here,

109
00:08:14,270 --> 00:08:20,860
now let's see what went wrong here on the backend by expanding this log and we cannot read DB of

110
00:08:20,860 --> 00:08:23,140
null is the problem here,

111
00:08:23,170 --> 00:08:25,720
yes because DB name here of course does not exist,

112
00:08:25,720 --> 00:08:32,800
I don't have such a variable. My DB name is locations, so we should just enter locations here,

113
00:08:32,800 --> 00:08:37,570
I remove that DB name constant from the example or didn't add it to be precise.

114
00:08:37,570 --> 00:08:42,940
So we want to connect to the locations database or use the locations database to which we connect here

115
00:08:43,730 --> 00:08:49,370
and now with that changed, let's restart this backend server and

116
00:08:49,370 --> 00:08:55,560
let's give this another try by again finding a new place here and now this didn't throw a new error,

117
00:08:55,590 --> 00:08:56,690
if I cleared the errors,

118
00:08:56,700 --> 00:09:01,980
we don't see a new error here and indeed here we get a success response and this is the object we get

119
00:09:01,980 --> 00:09:08,550
back by MongoDB, quite a complex object. In the end what it will have though is an inserted ID property

120
00:09:08,550 --> 00:09:10,480
which is just what we need here.

121
00:09:10,500 --> 00:09:19,040
So we send back here not ID but r.insertedId, that's what I want to send back to the client

122
00:09:19,810 --> 00:09:24,020
and now we don't need to generate our own ID here anymore. With that

123
00:09:24,030 --> 00:09:28,200
if we now restart this and we find a new place,

124
00:09:29,340 --> 00:09:33,980
now you see here we got this ID which is generated on the backend.

125
00:09:34,230 --> 00:09:41,310
So with that we're storing data in MongoDB, now retrieving it would also be nice when we send the get request

126
00:09:41,940 --> 00:09:46,550
from this page because right now of course we fail here because we have no logic to retrieve our data

127
00:09:47,070 --> 00:09:50,390
but the MongoDB driver docs got us covered. Here

128
00:09:50,400 --> 00:09:58,140
if we scroll down, we find more functions we can execute, for example for updating and for deleting documents

129
00:09:58,160 --> 00:10:02,190
but I want to find a document,

130
00:10:02,190 --> 00:10:05,880
so we want to have a look at the read methods here and there,

131
00:10:05,880 --> 00:10:12,510
again we have all the logic for connecting. In the end, what we can do here is we can just copy this code

132
00:10:12,510 --> 00:10:20,220
here from our add-location route into this get route here

133
00:10:20,400 --> 00:10:26,310
after we retrieved the location ID, effectively replacing this code where we use the memory database

134
00:10:27,120 --> 00:10:33,390
and I still want to connect to my client here, reach out to the database and reach out to the user

135
00:10:33,390 --> 00:10:39,360
locations collection but now of course I don't want to insert one, I want to find one document instead

136
00:10:39,360 --> 00:10:46,230
and you still pass an object to find one but here, you specify the criteria for finding a document and

137
00:10:46,230 --> 00:10:48,730
you can find a document by ID here.

138
00:10:48,990 --> 00:10:55,530
The ID is actually stored on an _id field in MongoDB, so we can use _id here

139
00:10:56,040 --> 00:11:01,340
and then use the extracted location ID which no longer should be a number,

140
00:11:01,350 --> 00:11:04,490
so let's remove the plus here as a value.

141
00:11:04,530 --> 00:11:10,890
So now we will try to find a document where the ID is equal to that location ID as a string which

142
00:11:10,890 --> 00:11:13,630
we retrieved from the URL.

143
00:11:13,740 --> 00:11:18,630
Now we have to pass a second argument to find one which is this function which executes once this operation

144
00:11:18,630 --> 00:11:19,380
is done,

145
00:11:19,470 --> 00:11:24,070
we either get an error or we get the document which we are looking for

146
00:11:24,180 --> 00:11:26,570
and here I expect to get the document,

147
00:11:26,610 --> 00:11:32,580
so when we return something here, I of course want to use this logic from before.

148
00:11:32,640 --> 00:11:39,540
I'll cut that code and add it here and check if we don't have a document for some reason, in which case

149
00:11:39,540 --> 00:11:46,480
I still return the not found error but if we did find one, then I wouldn't return a response where the

150
00:11:46,480 --> 00:11:50,130
address can be found on the document,

151
00:11:50,230 --> 00:11:58,860
there it is stored such that we have an address property and also get the coords from the document and

152
00:11:58,860 --> 00:12:03,400
the rest should be able to stay as it is. So let's give it a try,

153
00:12:03,430 --> 00:12:12,610
let's save that and rerun the server here and now let's reload this place. Now I still get could not

154
00:12:12,610 --> 00:12:18,540
find location and the reason for data is something MongoDB specific,

155
00:12:18,540 --> 00:12:24,790
the ID of an element which is added to the database is not actually a string,

156
00:12:24,870 --> 00:12:30,660
it's a special data type MongoDB uses internally, it's an object ID which is not a Javascript

157
00:12:30,660 --> 00:12:35,970
data type but a MongoDB specific one. Now when you query for an ID here, you therefore have

158
00:12:35,970 --> 00:12:44,640
to look for a such an object ID data type. You can do so by using that Mongo client, thankfully it's

159
00:12:44,640 --> 00:12:51,070
not too hard to do that however. When we import our MongoDB package here, we can not just reach out

160
00:12:51,070 --> 00:12:52,440
to the Mongo client here,

161
00:12:52,860 --> 00:13:01,730
let's restructure this a bit and import MongoDB here just from MongoDB and get the client then from

162
00:13:02,360 --> 00:13:08,270
MongoDB.client so that we can get other things out of MongoDB as well because the other things

163
00:13:08,270 --> 00:13:15,710
I'm interested in in this case here is this object ID constructor. We can use MongoDB object ID

164
00:13:15,710 --> 00:13:21,260
here and call new in front of it because this actually is basically a class which you can construct

165
00:13:21,740 --> 00:13:24,580
and to that, you pass your ID as a string,

166
00:13:24,620 --> 00:13:30,620
so in our case location ID and it will wrap this in its own data structure which now can be used in

167
00:13:30,620 --> 00:13:35,230
a query and with that change made, we restart that server,

168
00:13:36,790 --> 00:13:42,500
we can go back here, reload this place and we get this place here and that's it.

169
00:13:42,520 --> 00:13:44,950
Now this is by no means a finished server,

170
00:13:44,980 --> 00:13:54,010
we could do far more on this server, improve error handling, add more scenarios, make this code more reusable

171
00:13:54,040 --> 00:13:59,700
and not always create a new connection here but this is just there to get you started with Node.js

172
00:13:59,700 --> 00:14:04,300
and even MongoDB which is not directly related to Javascript after all

173
00:14:04,300 --> 00:14:09,010
and it's there to show you how Javascript is able to run in different environments and how you generally

174
00:14:09,010 --> 00:14:16,200
have the same syntax but still can do very different things with it and that's therefore it for this module.

175
00:14:16,390 --> 00:14:22,180
As I mentioned multiple times, if you want to learn more about Node.js and/or MongoDB, I got dedicated

176
00:14:22,180 --> 00:14:28,000
courses for that, in my Node.js course for example, I also spend a lot of time on MongoDB diving way

177
00:14:28,000 --> 00:14:33,940
deeper into it and showing you how you can connect it to Node.js in various different ways and therefore

178
00:14:33,940 --> 00:14:37,190
these are the resources you want to dive in if you want to learn more,

179
00:14:37,210 --> 00:14:42,760
this hopefully still gives you a great overview of what you can generally do there and how that works.
