Press "Enter" to skip to content

MERN Stack & GraphQL – #15 Query Population


so if we were to execute it now this
will create the eat chat so what we can
do in the users is we can fire Ralph a
query to get the chats this one is going
to fail the reason it feels is because
the chat property doesn’t return an
array of chat objects it returns an
array of ID’s so if you were to look at
the user model this one has a chat
property but this is an array of object
IDs so it sounds like we need to go back
to the user resolver and we need to
specify a custom resolution logic for
the chats of the user and I’ll put in
the key referring to the user and we’re
going to specify chats on it once again
it’s a regular resolver with the
exception that the root object in this
case is going to be the actual user
model we’ll have the arts contacts if we
need to info and what we need to do is
we need to somehow resolve the chats
property so what we can do is we can use
the populate method we can specify the
chats property and we’re gonna call it
on the user object so what this will do
is this will populate the user with the
chat objects so if before the user was
an object with chats where the chats was
an array of IDs like I’d say 1 2 3 after
you call the populate method this will
populate the array with the actual chat
object so what do we need to do is we
need to call a weight on it and because
of the promises syntax we also need to
call exact populated after the populate
method so finally we’re gonna need to
also add the ACE and keyword and I’m
after we’ve done that we can return user
dot chats or otherwise what we can also
do is we can have a return statement on
the same line we can wrap the await with
parentheses and because it’s gonna
return the newly updated or newly
populated user object we can just simply
write dot chats on it like that now
let’s go back to the browser if we run
the same query again this time it’s
going to work and it’s gonna give us all
at chats but not everything is going to
work yet because if we tried let’s say
messages this will fail once again
because we don’t have any messages
property on the chat once again it’s the
same exact scenario as with the user
except in this case we don’t have the
messages property at all so we can do is
we can go back to chat we can create a
new chat key we can create a messages
resolver so we’re gonna resolve the chat
we can have any herbs context and info
if we need to and now because every
message is going to have a chat ID
property on it what we can do is we can
simply have a message dot find and we’re
going to find all the messages such that
the chat property equals chat ID and we
can return that and once again if you
look at the message model the chat
property once again it’s gonna refer
back to the chat so now if we try it
again this will at least give us an
empty array but if you went further so
let’s say you try to get the users for a
given chat once again this is gonna fail
same exact thing because the user’s
property on the chat in the database or
in MongoDB actually contains an array of
object IDs but for graph QL we need to
return an array of actual objects or
actual models so what we’re gonna do is
we’re gonna return back we’re gonna call
an await on chat populate so we’re gonna
populate the users and once again this
will be an arrow function with an async
keyword so once we populate it let’s do
exact populate and we’re gonna return
the users out of it in this of course is
users not user so if we try to run it
again so now we get the chats with the
users inside of them and finally we
don’t have the last message yet but if
we were to the call would also fail in
this time because the last message is an
object ID once again so we can define
last message on the chat and this will
be an async function we’re gonna
populate the last message and we’ll
return the last message so now if we run
it of course we won’t get any results
yet but at least we’re gonna know that
in a long run there should work and of
course as far as the messages go we also
need to do pagination in here because
right now we are returning all messages
but in fact there could be millions of
them so we need to paginate them and we
could also work on projection here as
well in fact projection applies to just
about any resolver in this file or even
in this project you know since we added
a custom object ID validator what we can
do is we can go back through the user
resolver and we can actually get rid of
this condition to validate the object ID
what we can do instead is we can use joy
for this purpose so we can call a joy
that valid a
we’ll pass any args and we’ll pass in
the schema in this case we can call it
object ID so we need to get access to
the arts object so in here we’ll do our
X dot ID and we’re gonna do in a weight
on this it’s all we need to add the
async keyword so now we can get rid of
Mongoose and also user input error so
for the object ID it’s possible that
this type of validation is going to
happen in other places as well so we’re
gonna make the object ID generic so
let’s go back to schemas I’ll create a
new file it’s called utils a s so in
here we’re gonna import joy from joy in
this case we need to import it from the
same directory because we need to get
access to the object ID custom validator
that we’ve created
so let’s export a Const of object ID so
this’ll be joy dot object and it’s gonna
have a single key of ID so this will be
joy at string dot object ID and the
label we can give it object ID like this
so with that if we go back to index we
need to export everything from utils and
now we should be able to import it from
schemas so now let’s go back to the
browser I’m gonna try to do a query on
user so let’s pass in an empty string
this will fail the object ID is not
allowed to be empty if I pass in
gibberish this will fail again because
this must be a valid object ID now if I
pass in the ID of this first user this
will succeed and that would be myself
now if I change the ID to something
that’s not existent in the database I’ll
get user of null and that makes sense
because the user but that ID doesn’t
exist it’s the last thing I’ll do is
let’s switch back to our second user
we’ll do a me query on chats so let’s
get all the chats by ID let’s get all
the messages maybe also last message and
it looks like it worked the only issue
that we didn’t tackle is the title so
what happened right there is that we’ve
created a chat that doesn’t have a title
and because we specify the title as a
required property we cannot return null
for that chat field so I think what we
could do for the title is we could
generate the title based on the names of
the users so for instance if you pass a
valid title that title will be supplied
to
the chat when the chat is being created
but if the title was not supplied what
we could do is for the chat we can
assign that title to a string that
contains the names of the users so let’s
say for example if I’m Alex this would
be Alex the second user in this case is
Mac so they’ll be like comma max and if
we had more users we could also add them
lastly if we let’s say 50 different
users we could just simply display let’s
say five so for example Alex max
ray Jim and Kyle and leave off the
string web and ellipsis to indicate that
there’s actually more users because
especially in the UI will be difficult
to display a full list of users so this
is something that we could do for the
title and of course we could put all
that logic to add the names of all the
users in this file but it makes sense to
extract out something like this to the
model so let’s actually take it out
let’s save the file for the time being
and close off everything else let’s open
the chat model so what we could do is
just like we did inside of the user
model where we added the pre-safe hook
we could do the exact same thing for the
chat model in fact let me copy it so
I’ll bring it back in here so on the
chat schema we’re gonna define a
pre-safe hook and this one will fire
when creating a chat so if I were to go
back to the resolvers we have the create
call this call will trigger the pre-safe
hook so what we’re gonna do is we’re
gonna check if this chat has a title and
if it doesn’t we’re gonna have to assign
it ourselves so in the end what we need
to do is we need to do this dot title
assign it to something so what we could
do is we can get hold of the user model
so we could do user dot we’re ID is
inside of the range of the stat users
once again in the resolvers the users
property is going to be the list of all
the user IDs so we’re gonna find all the
users that belong to that users array
and all just important user from the
current directory we’re gonna set a
limit because as I said before we want
to shorten the title if there’s too many
users for example we can shorten the
title after five users or five names so
let’s create a constant user limits we
can set it to five so we’re gonna fetch
as many as five users
and we’re gonna select the name of each
user so we’re gonna do Const users let’s
do an await on it so now to get the
names of the users wicket two names this
will be users dot map so we can take out
the name of each user and we can
basically join them with a comma so now
we can say if the stat users that length
exceeds the limit so the user limit that
we’ve defined so there’s more than five
participants in a chat we’re gonna need
to modify the names
so let’s actually make this a mutable
variables so we’re gonna use light
instead of Const and we’re gonna say
names let’s actually rename it to title
because we’re gonna be setting the title
for the chat so if we reach the limit
we’re gonna simply add the ellipsis to
the end of that title string and we’re
gonna assign it to this dot title so
let’s see if this worked I’m going to do
is I’m going to modify e to users so I’m
going to delete the chats reference for
both of them alright and now you can
also delete the chats collection I’ve
already done that but back in here let’s
see if we could do a query on myself
with the chats the ID users also
messages if there’s any so now we don’t
get any chats and that’s expected so if
we were to write out a mutation let’s
start a chat I’m gonna grab the ID of
the second user which is Macs
so I’ll fill out the user IDs let’s get
ID and title and I’m gonna save this to
the queries file just so we can reuse it
afterwards and let’s do the same thing
for this users query in fact Ally to the
last message as well right so if we run
it this will create the new chat and as
you can see it filled out the title as
well so now if we run the same users
query we’re gonna get the users with the
chats so as you can see if I switch back
to me just for simplicity are you gonna
get back myself so we’re gonna get my ID
and we’re gonna get the list of chats in
this case it’s an array that contains a
single chat so it has an ID of that also
has a list of users so in this case
we’re not getting a list of object IDs
because in fact now I can actually get
their names of those users we also get
the messages property but for now it’s
empty and we get the last message which
is null
for now but that’s expected later on
we’re gonna also work on the circular
issue because right now on the user’s
subselection we could do a chats query
we can get the idea of all the chats but
it could also get the users of all the
chats and we can also get the chats of
those users so you can see that we can
go in as many levels as we want so
there’s actually ways to mitigate that
but we’re gonna look into that later and
for the time being we’re gonna leave it
off like that
so this is basically it for chats and
the next one we’re gonna work on messages so I’ll see you then

Please follow and like us: