This course will be retired on August 10, 2021. We recommend "REST APIs with Express" for up-to-date content.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
In the last video, we saw how to connect to Mongo with Mongoose, how to create Schemas to represent the data we want to save, and how to create models from those schemas to make, save and retrieve documents from the database. This video looks at some ways we can extend these tools to make working with our data more convenient.
In the last video, we saw how to
connect MongoDB with Mongoose,
0:00
how to create schemas to represent
the data we want to save, and
0:04
how to create models to save and
retrieve documents from the database.
0:08
Let's take a look at some ways we
can extend those tools to make
0:12
working with the data more convenient.
0:17
First let's clean up our sandbox a little.
0:20
There's a method we can call on
the animal model that saves a batch of
0:23
documents in the database, create.
0:28
We can pass the create method an array of
models or objects or a mix of the two.
0:32
We'll do exactly that,
0:37
create an array of a mix of JavaScript
object literals and models.
0:39
Let's see this in action by creating
an array of a few more animal
0:44
objects called animal data.
0:48
Let's create a mouse, Who's gray,
1:03
Who weighs 0.035
1:19
kilograms called Marvin.
1:23
A nutria,
1:37
Who's brown, Who weighs,
1:45
6.35, Whose name is Gretchen.
1:56
A wolf, Which is gray,
2:12
weighing 45 kilograms,
2:21
named Iris.
2:27
And finally, the three existing models,
2:30
elephant, animal and whale.
2:36
We can use this array to
store them in the database.
2:40
Notice there are no size
properties on these objects.
2:46
In fact,
let's delete them from our other animals.
2:49
And we can remove the default
value from our schema.
2:59
We'll see how to add this property
back on dynamically in a moment.
3:08
For now,
we can delete the three animal save calls,
3:13
and replace it with one create
call on the animal model.
3:17
We can pass in our array of animal data.
3:36
And the callback has an error, and
then the animals that were saved.
3:43
Let's remove these extra closing
brackets that we don't need anymore and
3:51
clean up our code a little.
3:57
Much nicer.
4:14
Now let's see how to set
the size property of each animal
4:17
dynamically before saving
them to the database.
4:21
Mongoose offers us something
called a pre-save hook.
4:25
This is an opportunity to do something
to a document before it is saved.
4:29
We can take advantage of this opportunity
by writing Mongoose specific middleware,
4:33
passing it into the pre
method on a schema.
4:40
Let's implement a prehook
middleware on AnimalSchema.
4:49
The handler we're passing into as
the second parameter will execute
5:15
before Mongoose saves
the document to the database.
5:19
It takes a next parameter that will be
used in the same way as in Express.
5:23
Once we're done with our code, we can
call next to tell Mongoose we're done.
5:27
Inside this handler,
5:38
the this object will point to
the document or model to be saved.
5:40
Let's use this handler to
examine the mass of an animal.
5:46
We can assign the size
property based on the mass.
5:56
If the mass is greater than or
equal to 100,
6:01
This size is big.
6:11
If the mass of the animal is
greater than or equal to 5 or,
6:23
Is less than 100, Then its size is medium.
6:32
Finally, if it's anything else,
it's small.
6:49
To test this out and see the results,
we can alter the query we had below.
6:57
If we pass in an empty object
as the first parameter,
7:07
the query will return all objects.
7:11
Then, inside the callback,
we can log each animal's size so
7:16
that we see that it was set.
7:20
Now if we save this, switch over
to our terminal and run our file,
7:38
we should see that the sizes
are assigned correctly in the output.
7:44
As you can hopefully see,
pre hooks can give you a lot of power.
7:59
Save isn't the only event
that has pre hooks.
8:05
You can find out more about them
in the documentation linked in
8:09
the teachers notes.
8:12
Let's see how to use this size property
in a custom query called a static method.
8:23
A static method is a custom function
we can call on the model directly
8:28
to help us access our data in custom ways.
8:33
For example, what if we often find
ourselves needing to find small animals?
8:36
We could write the query every time,
or to save some typing and
8:43
dry up our code, we could put
the query into a static method.
8:47
On the animal schema,
there is a statics property.
8:58
This is where we can
define our static methods.
9:04
Let's create a static method on
the animal model called findSmall.
9:08
We're passing in a call back here,
so it can plug into the query inside
9:25
the function to preserve the flow
of our overall application.
9:30
This inside the static
method refers to the model.
9:49
In this case, it will equal the animal.
9:53
We can use this model to
query the collection of
10:04
documents with the size property of small.
10:08
Let's update our query to see
the results of the static method.
10:12
Now when we run this file,
we should see our mouse and fish.
10:30
Let's generalize this method.
10:43
Instead of just small animals,
let's enable this method to work for
10:46
any size we specify.
10:51
To do that, we can change the function
to be called, findSize and
10:53
pass in and
arguments as the first parameter.
10:58
And then modify the query
object to include the size too.
11:07
Down at our query,
change findSmall to findSize.
11:19
With the first argument, medium.
11:25
I'll let you test that out on your own,
if you'd like.
11:33
Static methods can be really helpful
11:36
when we want to create custom queries
from the perspective of the model.
11:39
But what if we wanted to find data based
on a document that we already have?
11:43
For example,
what if we want to find an animal, and
11:48
then we want to find more
animals with the same color?
11:51
We can use instance methods for this.
12:01
Instance methods exist on all documents.
12:04
In instance methods, the this value points
to instances of the document itself.
12:07
To create an instance method,
we'll first place
12:14
a function on AnimalSchema's
methods property.
12:19
Let's call our method findSameColor.
12:25
To get a reference to the model, we can
call the document's model method and
12:48
pass in the name of the model
we wish to access as a string.
12:53
In this case, it's animal.
13:06
From there we can query the usual way.
13:09
Passing in the documents
color with this this.color.
13:12
To see this in action,
we'll need to modify our query once again.
13:31
Let's use the Animal model's findOne
method to retrieve an elephant
13:36
This method will search the database for
13:54
batches and whichever is first
to match is the one returned.
13:57
This is good if you only want one
matching document in the database.
14:02
We can use the resulting document
to call the instance method and
14:07
print out the results to the console.
14:11
Now when we check
the results in our terminal,
14:57
we see we get all the gray animals.
15:01
Success, now that we've seen how
to use static and instance methods
15:04
to customize the way we handle
database interactions with Mongoose.
15:10
We've also seen how to
implement a pre save hook.
15:14
There are other features Mongoose offers,
and I'd encourage
15:17
you to read the documentation
linked in the teacher's notes.
15:21
Feel free to play around in the sandbox,
too.
15:24
When you're ready, we'll start integrating
Mongoose into our Express app.
15:28
You need to sign up for Treehouse in order to download course files.
Sign up