Hi guys. Welcome to a new module. Now a few modules back
we built those beautiful to do list.
And in the process we learnt about a whole bunch of things such as how to use EJS templates and how
to pass data between your server and your EJS files.
Now there's just one problem with this app as it is though.
Because if we added in a new item, let's say "Test" and it looks great
and you know when we refresh it it's still there.
But if I go ahead and just restart my server,
so at the moment I'm running app.js using nodemon.
So if I just type in "rs" into the command line and hit enter then it will restart my nodemon server.
And this is equivalent to say if you are running your app using node app.js then every single time
you make a change in your app.js then you would have to rerun node app.js and nodemon basically
does that automatically behind the scenes.
But you can also just get it to restart the server by just typing "rs".
So now we've restarted our server.
And if I now take a look at our localhost:3000 if I go ahead and refresh this website you can see
that that item that I just added disappears.
And the reason for this is because currently all of these items are stored inside an array and every
single time I restart my app.js, I rerun it, then it wipes that array to the default items that
we began with.
And all of the new items I added gets wiped out and it's no longer saved in our app which is not a great
user experience to be honest.
Now that we've learned about databases and how to persist our data then this is a perfect use case.
So we're going to update this app to start using MongoDB to save our data to a MongoDB database
and you'll see that afterwards no matter how much I restart my server or whatever changes I decide to
make to my app.js or the rest of my website all of my data will be safely saved in our database.
So let's get started.
So in the last lesson you should have gotten hold of the starting files for the second version of our
To-Do list.
If you go ahead and just unzip it and place it on your desktop or into your development folder then
we can drag it on to Atom and we can get started.
Now the first thing you'll notice is that we don't actually have a Node modules folder.
And that is of course because whenever we download something from the internet usually it won't come
with the Node modules
so we have to cd over to the location of our folder and then just run npm install or npm i in that
folder.
And then it'll go and look at all the dependencies we have in our package.json for example body-
parser, ejs, and express. And it will install it and create our node_modules folder.
So now that we're ready to upgrade our todo list to a version that actually has a database on the
backend, then the first thing we should look at is, how are we storing our data currently?
Well we currently have this constant called items which has an array of default objects to begin with.
And then when we add or post new items into our app.js, then we push those items into the relevant
arrays.
So for example the items array or the workItems array.
Now we're going to delete all of these arrays and we're going to be using Mongo and Mongoose instead.
So the first thing we have to do is we have to install Mongoose of course.
So let's go ahead and run npm install mongoose.
Now that should add that to our package.
json and it'll add the relevant modules into our node_modules folder.
So now that we've got access to our node modules, we're going to now require our Mongoose.
So we're going to create a constant called mongoose and it's going to be requiring the mongoose package
that we just installed.
The next thing that we need to do is to go ahead and create a new database inside MongoDB.
The way that we do that as we've seen before in previous modules is mongoose.connect and then
the thing that we're going to connect to is the URL where our MongoDB is hosted locally which
is traditionally
"mongodb://localhost:27017".
And then we're going to write one further forward slash and we're going to specify the name of our database
which in this case I'm just going to call todolistDB.
And then finally remember if we wanted to not have that little warning show up if we want to avoid that
deprecation warning, then we have to add that little flag in there which is "useNewUrlParser
: true".
And at some point in the future you won't have to do this anymore because Mongoose and Mongo will update
their code
but for now if you're seeing that deprecation warning when you don't have this in, then this is the way
to work around it.
So now that we specified how we're going to connect to our MongoDB and which database we want it to create
or connect to,
then the next step is to create a new schema
right?
And we want to create a new items schema.
I'm going to leave this up to you as a challenge.
I want you to create something called itemsSchema and this is only going to have one field which is
called name and the names of each of our items are simply going to be of data type string.
Remember, this is roughly what a Mongoose schema would look like.
We have the const keyword, then we specify the schema name and then we set it to equal a new Javascript
object with a key value field.
And the key is going to be the name of the field and the value is going to be the data type of our field.
So you've done this before.
Pause the video and try to complete the challenge.
So this is pretty simple.
All we have to do is create our const and then we create our itemsSchema.
And this is going to be equal to whatever field it is that we want into our schema and we're only going
to have one field which is going to be the name of the item and the name is going to be of course a
string data type.
Now we have our item schema,
the next thing we need to create is a new Mongoose model based on this schema. Again as a quick reminder
this is what Mongoose models look like.
We create a new constant and we use the mongoose.model initialiser to create that new model.
And in order to create it we have to specify two things: the singular name of our collection,
so if we had a collection called people then the singular form would be person and that has to be in
the form of a string.
And then we have our schema which we provide. Pause the video and try to complete that challenge.
All right.
So we've already created our schema and we now have to create our model based on the schema.
Let's create a new constant and we'll call our model Item with a capital "I".
So remember whenever you have a Mongoose model it's usually capitalized.
And this is going to be equal to a mongoose.model and we're going to create the model passing in
two arguments.
The first thing is the singular version of our collection name.
So we're going to have a collection called items and that means that the singular version is going to
be item. And then the second argument is going to be the schema that we're going to use to create this
item's collection which is of course our items schema that we created a little bit earlier on.
So now we have a schema and we have a model created using that schema.
The next thing I want to do is I'm going to delete everything that's related to this day and getDate.
I'm just going to simplify our code a little bit instead of having to use our date module and instead
of having this data file, we're going to just simply render the default list with a title that's called
"Today".
And this way we'll cut down the complexity of working with the date and the external modules and also
trying to understand how MongoDB is going to be plugged in to our app.
So this just makes it a little bit easier to understand. Now that we've replaced the list title with
a simple string
the second thing we're passing over to our list.
ejs is our items array, which if you remember we deleted so it no longer exists.
And instead we want to pass over the items that are inside our items collection. To do that we need some
default items right?
So let's go ahead and create three new documents using our brand new item Mongoose model just around
here
and I'm again going to leave that up to you as a challenge. Just as a reminder, the way that we create
new documents using Mongoose is something like this.
So we would create a new constant then we would bind it to a new model name,
so in this case that would be item. And then we specify the values for each of the fields in our schema.
We've done this before.
And so I want you to pause the video and try to create three new documents which will be the default
items in our To-Do list and they can say whatever it is you want them to say.
Following that format
we're going to create our item1
and this is going to be a new item.
So we're saying that we're creating a new document from our item model and then we pass in our fields
right?
So the field that is called name is going to say "Welcome to your todolist!".
And that's one document out of the way. Now I'm just going to go ahead and create two more.
So now I've created three documents item1, item2 and item3 and they have some arbitrary names.
So the first item is just going to say "Welcome to your todo list!",
the second one is going to say "Hit the + button to add a new item."
and the third one's just going to say "Hit this check box" or "Hit this thing over here to delete an item".
Now that we've got our three documents, let's go ahead and put them all into an array.
And I'm just going to call this the defaultItems.
It's going to be a new array and it's just going to contain item1, item2 and item3.
Now that we have our array then we could use one of the methods in Mongoose called insertMany so that
we get to insert all of these items in one go into our items collection. Again just as a quick reminder
of how the syntax for insertMany looks like,
then you can see it looks something kind of like this.
We provide the model name which refers to the collection that we want to insert our data into, and then we
provide the actual array of documents that we want to insert
and finally get a callback which may or may not contain an error
depending on how the process went.
So while I'm showing you a lot of syntax using slides, you can also of course just simply read the docs
inside Mongoose right?
So if you go to the docs and you go over to the API and find the model API docs then you can find these
things such as insertMany and see the full explanation and example as well. So don't feel like you
have to rely on just the hints I've given here.
Coding is essentially an open book exam. You can refer to as many sources as you like in order to get
to the answer.
Pause the video and try to insert all of our items into our items collection.
All right.
So in order to insert it we're going to specify that we want to insert our items into the items collection.
So we'll refer to the item model. And then on that model we're going to call insertMany and we're going
to provide two arguments.
One is what do we want to insert.
Well we want to insert our array of defaultItems.
And the second thing is we have to provide a callback just in case there's any errors.
So we could say something like if there's an error then log the error, else simply log success
fully saved default items to database.
Just before we run our app.js
just make sure that you check your code that there's no errors anywhere, that you've got everything all
set up with your model, your schema and your documents.
Over here I've just spotted it.
I've actually got a bit of a typo. Instead of user
it should be useNewUrlParser. Now that I'm happy with my code
then it's time to head over to my console and make sure that you've got a mongod process running.
So you should have this set up from the last module.
And we should also have a mongo shell that's enabled on another tab as well.
So now make sure that you've cded over to where your app.js is
and we're finally ready to run our app.js.
So now if I hit enter, you can see that we get the service started but also we get the message that
says "Successfully saved our default items to database".
If we switch over to our Mongo shell and we say "show dbs" then we now have this extra database
code todolistDB.
And if we go ahead and say "use todolistDB" and now we "show collections" you can see we've now created
this collections called items and this is all done when we created our Mongoose model and specify the
singular name of our collection.
So now if we say "db.items.find" basically find all,
now we've got three documents saved in there which correspond to our default list that we want to show
when we create a new todo list right?
So that was pretty successful.
Now if you have any problems with starting up your Mongo shell or with your mongod server then just
have a look inside the course resources for this lesson where you can see some ways of debugging what
the issue is and fixing it if needed.
But hopefully you're on the same page as me
and you've got your server started and you've successfully saved your items.
The next step is to read from our database inside our app.js.
So for all of that and more, I'll see you on the next lesson.