Teacher: So remember how in the video
about our data model, we said that
we could either embed or reference
the tour guide data, so in this video
I'm gonna show you how we could implement embedding
tour guide documents into a tour document.
So again, in this lecture we are going to
embed user documents into tour documents,
and then in the next video, I will show you
how we can actually reference users
instead of embedding, all right?
So the idea here is that when creating
a new tour document, the user will simply
add an array of user IDs, and we will then
get the corresponding user documents
based on these IDs, and add them
to our tour documents.
So in other words, we embed them into our tour, okay?
So, let's do that here now.
So guides will be of the type array, okay?
Very simple, and actually before we implement
any code, let me show you as an example
how this would work when creating a new tour.
So, let's go back to Postman here,
and create new tour,
okay, and so here in our body
we of course would now add the guides,
quotes, and then specify an array of IDs, okay?
So, let's get some user IDs.
So, get all users, let's see what we have here.
So we have a guide here, actually,
and so let's get this ID
along with the quotes, actually,
and so let's put that here,
and let's add some other ones.
So, this here as well and actually just these two.
That should be enough for testing this stuff, okay,
and so this is then how we're gonna create
a new tour with two guides, okay,
and again once we then save this tour,
we will then, behind the scenes,
retrieve the two user documents
corresponding to these two IDs, all right?
So, let's implement that,
and back in our model
the best place of doing that
is a pre-saved middleware, right?
So, that will then happen automatically
behind the scenes, basically,
each time that a new tour is saved,
and actually, I don't want to do it here.
So we have query, here,
here's the document "Middleware,"
so let's do that here.
So tourSchema.pre,
All right, let's call next right away here,
so that we don't forget it in the end.
Okay, so we get this.guides as an input,
and remember this is gonna be an array
of all the user IDs, right, and so we
will loop through them using a .map,
and then in each iteration get the
user document for the current ID, all right,
and we're gonna store that inside of guides, all right?
So, the current element, which is gonna be the ID,
well let's actually call it ID
to make it a bit easier understand,
and so now we actually need the user, right,
so let's go ahead and import that.
So, const User,
require,
and it's actually in the same folder here, all right,
so User.findByID
with the current ID, all right?
But now, keep in mind that we actually
do need to await this promise here, right
and so, therefore, the function needs
to be marked as async,
but now we actually get a problem, all right,
because the .map method will assign
the result of each iteration to the new element
in the guides array, okay, and so now
we have an asynchronous function here
and, as you know, that returns a promise,
and so right now this guides array here
is basically an array full of promises, okay.
Let's actually call this guidesPromises
and so we now actually need to run
all of these promises, basically at the same time.
As I showed you a bit earlier in this code,
at least if you didn't skip the
asynchronous JavaScript section,
all we need to do is await Promise.all
and then guidesPromise,
okay, and we can directly assign the result
of this to this.guides,
and so basically override that temple array
of IDs with an array of user documents, okay,
and since we're now using await here,
we need to mark this function as async, okay?
Give it a save, and I think that's actually it, okay?
So again, we need to use Promise.all here because
the result of all of this here is a promise, okay,
and so this array here is gonna be an array
full of promises which we then run
by awaiting Promise.all, okay?
So, let's actually test this out now,
and we already have all of this code here ready,
we should just change this name here.
So, 'Test Tour,' but the IDs are already here.
So let's send this, and our tour name
needs to be longer, 'New Task Tour.'
Okay, but now let's take a look at our results,
and so indeed we get our guides here, okay?
So these are the complete documents,
and indeed not just the IDs, right?
Great, and so this is how we could
implement embedding for this tour guides example.
Now, this simple code that we implemented here
of course only works for creating new documents,
not for updating them, right?
So now, we would have to do go ahead
and implement this same logic also for updates.
However, I'm not going to do that because,
remember from the video where we modeled our data,
that there are actually some drawbacks
of embedding this data in this case.
For example, imagine that a tour guide
updates his email address, or they change
their role from guide to lead guide.
Each time one of these changes would happen,
then you'd have to check if a tour
has that user as a guide, and if so,
then update the tour as well,
and so that's really a lot of work
and we're not gonna go
in that direction, all right?
Now, I still wanted to show you
how embedding really works, and how
we could implement it in this situation
because I really believe it's very important
that you still know how to do everything
in case you ever need it
in your own applications, okay,
but in this particular situation we will,
instead of embedding, use referencing,
and I talked about reasons for doing so
back in that video, okay?
So, let's actually go ahead and do that
right in the next lecture.