Press "Enter" to skip to content

MERN Stack & GraphQL – #14 Creating a Chat


so if we were to think about the graph
QL schema in terms of Corrections the
first thing that would make sense to
implement on the chat type let’s say
would be to first of all create a chat
because right now we could write a query
to fetch all the chats for a user but it
doesn’t really make sense to do that
because we really don’t have any chats
in a database yet so first of all let’s
create the means to add chats to the
database so we’re gonna extend the
mutation type and we’re gonna write a
mutation to create a chat I think it
makes sense to call it start chat as in
starting a chat or starting a
conversation with someone so we’re gonna
accept a few arguments first of all
we’re gonna accept a list of ID’s well
in this case to be more specific it’s
gonna be a list of user IDs so this will
be an array of object IDs and this is
gonna be a list of users who are gonna
be part of the conversation and in the
end we might return the chat type and
besides that we might also accept a
title as a string but we’re gonna keep
it optional for the time being and the
last thing is I’m going to also add the
new author director that we’ve just
created
because if you’re not signed in you’re
not allowed to create a chat you have to
first sign in so with that let’s go back
to resolvers we’re gonna create a new
resolver let’s call it chat is so in
here we’re gonna export default an
object so we’ll have a mutation we’re
gonna have start chat with the familiar
arguments roots args context and info
I’m gonna save the file and then back in
index we’re gonna also import chat from
a chat and we’re gonna export it as part
of the array and then when creating a
chat we’re gonna have to do a bit of
validation first we’re gonna call joy
dot validate we’re gonna pass in the
args the schema and we’re gonna also set
abort early to false so let’s first of
all work on the validation part so we’re
gonna import let’s call it start chat
schema from schemas so we’re gonna
create a new schema and let’s call it
chat is we’re gonna import joy from joy
so we’re gonna export a constant let’s
call it start chat so in here we’re
gonna call joy object dot keys so we’re
gonna pass in a bunch of keys so we’re
gonna have a title which will be enjoyed
string we could set the minimum line
six maximum to let’s say fifty and we
won’t make it required but we’re gonna
set a label to title and then four user
IDs
once again this is gonna be an array so
now if I go back to the browser so now
joy already has means to validate arrays
we just have to look at the API
reference so if you go to the array
section we have quite a few methods that
we can use for example the items method
is gonna allow us to list these specific
items that we want to allow for or
prohibit in the array so with that let’s
go back in here so we’re gonna call the
array method we could also use the
minimum and maximum methods the minimum
is gonna set a minimum limit the maximum
of course the maximum upper limit so
with that we can say let’s say the
minimum could be one element and the
maximum would be let’s say the maximum
in a single conversation would be a
hundred users all of those user IDs have
to be unique and finally we can call the
items method now in here we’re basically
going to define every object ID or every
string in the array so in this case it’s
gonna be joy dot string in this case we
actually need to validate that the
string is going to be an actual user ID
because would we basically expect for
the user IDs properties we expect it to
be an array but not an array of numbers
of course an array of strings but once
again not an array of simple strings
like let’s say alphanumeric characters
it has to be a specific type of string
so it has to be an object ID so we only
have a validation for an object ID
inside of the user resolver so if you
remember we had to do this part of
validation to make sure that the ID that
the client is passing is an actual
object ID so we actually run into the
same use case before so what I think
makes sense to do right now is to create
a custom validator for joy that is going
to validate object IDs specifically
because there’s not much enjoy that can
help us validate a string to make sure
that it’s an actual object ID so what we
can do is we can actually extend joy to
create a custom validator so I’ll create
a file let’s call it joy Diaz now
talking about extension if I go back to
the docs under the section that can help
us to extend joy to create a custom
validation rule so an example can look
something like this so we’re gonna call
joy that extend we can pass a function
or we can also pass an object we’ll
define
base for our evaluator we’re gonna give
it a name we’re gonna give it a set of
messages or just a single message if
it’s only one and we can call it either
the pre-hook or we can also define a set
of rules so what we’re gonna do is we’re
gonna come back and here first of all
let’s import Joey from joy so the custom
rule that we’re gonna define it’s gonna
be called object ID once again we’re
gonna call joy that extend we’ll pass in
an object so the base will be of course
joy dot string because we’re gonna be
extending a string and now name we’re
gonna call it string because we are
extending a string in the end as far as
the language goes so this one will be an
object so I’m going to call it object ID
and we’re just gonna say must be a valid
object ID and now for the actual rules
we’re gonna create an array this is
gonna contain a single object so we’ll
give it a name of object ID and we’ll
pass in the validate function so this
one is gonna take four parameters so
we’re gonna have params we’re gonna have
the value state and options and this one
is going to use the shorthand syntax and
so it’s gonna be a function as the
method on the object that we pass
through the array so inside of the
function we’re gonna check if the value
passed to joy is in fact a valid object
ID and for that we can basically go back
to our user GS and we can simply copy
that piece of code so let’s go back to
joy I’ll paste that in we’re gonna have
to import Mongoose from Mongoose and
we’re gonna check if the value is in
fact a valid object ID and now instead
of throwing an error so what we can do
looking back at the docs once again we
can return a call to this dot create
error instead so let’s do that we’re
gonna create an error you know the key
will be string which is the name of this
property dot object ID and the object ID
part refers back to the key on the
language object so we’re gonna reference
that message we’ll pass a nothing for
context we’ll pass in the state and
options from this function so the state
in options that we receive as arguments
and this function needs to be a
traditional function that’s why we’re
using me shorthand syntax and not an
arrow function because we need to have
access to via this keyword you know if
this condition fails so if it’s not a
valid object ID the condition we return
full so we’re gonna trigger an error in
joy otherwise
we’re gonna return back the actual value
and now what we can do is we can
actually export defaults and extension
of joy so let’s do export default
Joetta extend so we’re gonna call object
i t so instead of extending it in the
same constant we’re gonna export default
extension but we might also have
multiple constants in the future so
let’s keep it like that
so now let’s save the file and if we go
back to schemas we’re gonna be importing
joy from joy so it’s gonna be the joy
das file and because of that we’re gonna
have access to the object ID property so
this way we can say that the string has
to be an object ID and now the other
conundrum that we need to consider is
the ID of this signed end user so what
can happen is that the client who’s
sitting off the query can pass in an
array let’s say the first one is gonna
be the idea of user 1 but they can also
send in the ID of themselves so the user
that’s actually logged into the system
and this is gonna complicate the
conditions quite a bit so I think the
easiest way to go around this is to
prohibit the clients from sending their
own ID as part of the array so this way
once the validation is done we can
simply do arguments that user IDs and we
can push the user ID or the ID of the
assigning user to that array so now to
exclude something we can call the knot
method and we can fasten me user ID
inside and of course we’re gonna have
access to it so we’re gonna accept it as
the argument to that function and once
we get it we’re gonna make sure that the
array doesn’t contain that user ID
finally I’ll give a label to this string
we’re gonna call it user ID like this
and now on the users ID itself we can
also supply a label so this could be
user IDs in plural so now with that
let’s go back to index we’re gonna re
export everything from chat so we can go
back to the resolver and we can actually
do the import of star chat so we’re
gonna pass it as the second argument so
this is gonna be the schema and we’re
gonna need to also import joy from joy
so for the time being let’s just do in a
wait so this way we’ll have to make the
function asynchronous but this one needs
to be invoked as a function so we’re
going to need to pass in a user ID
so let’s actually destructor it for
request session and request the forces
gonna come from context so now that
we’ve done that we’re gonna return a
simple object from this mutation for the
time being but if we go back to queries
what I’m gonna do is gonna use the
sign-in query to sign in to the app so
let’s paste it in this is gonna sign me
in from then on we’re gonna write a
simple mutation this one is gonna start
a chat so we’re gonna pass in an array
of object IDs
so let’s here if we were to pass in an
empty array let’s see what’s gonna
happen this time the validation fails
because we’re passing in an empty array
let’s say I were to pass an empty string
this will also fails because it cannot
be an empty string it has to be an
object ID I’ll pass in gibberish this
also fails because now it’s not a valid
object ID again and I would say if I
were to pass in my own object ID this
should also fail and we get the user ID
contains an invalid value so that’s
perfect so now let’s open a new tab I’m
gonna do a query on users so let’s get
them by ID actually we only have a one
so in that case I’m gonna open in your
window let’s go to localhost 3000 I’m
gonna now copy the signup mutation and I
paste it in so let’s say we’re gonna
creating a user max at gmail.com with
the username of max so let’s try running
it okay so the username has to be four
characters long okay let’s actually
change that I’ll go back to schemas this
would be user J s I’m just gonna change
the minimum on the username to three
let’s try again so this will create the
user perfect you know switch back to our
main window now if we run again we’re
gonna get the second user so let’s pass
that object ID so this should succeed
now and the validation passes so that’s
perfect so now once the basic validation
succeeds what we need to do is we need
to verify that every single ID instead
of user IDs array is in fact valid but
not only valid from the perspective of
Mongoose as in being a valid object ID
but also being a valid user in the
database so it sounds like we need to do
a count on the user model where the ID
property is inside of the arguments dot
user IDs range so what we can do is we
can actually structure it so let’s get
the title let’s get the user IDs from
arguments so passing the user IDs and we
can do a count of documents on that
query so we’re gonna find all the
documents with the given IDs and we’re
gonna do a count on them you know this
one we can assign to a constant so
what’s the IDS found so how many IDs
were found in fact and this one needs to
be within a wait keyword as well because
this is asynchronous so we’re gonna say
if IDs found doesn’t equal the length of
user IDs so let’s say the clients
applied five different object IDs to the
user IDs array but if we were only able
to find four so if one of them is not
valid we’re going to throw new user
input error and this one we need to
point from a pole server express
actually it’s pulling it from a pull
server core because that’s the core
package Polo server express is simply
going to re-export it but either way
we’re gonna throw in an error let’s say
one or more user IDs are invalid we’re
gonna stay generic and now we also need
to pull in the user itself so let’s do a
user from models so let’s do a quick
return of an empty object so we’re gonna
go back in here let’s say I change the
ID from 64 to 63 the fetch right now as
you can see we get one or more IDs are
invalid if I change it back run it and
it passes so once again the way it’s
gonna work is it’s gonna do a count of
all the user IDs and we’re just gonna
say if the count doesn’t match the
number of IDs provided that means that
at least one ID was not valid and in
that case we’re just gonna throw in an
error but otherwise we could do user IDs
dot push so we’re gonna push in the idea
of this signed in user once again the
reason we have to do this is because we
want to add the user that’s signed in to
the conversation so from then on looking
to chat create we’re gonna pass in the
title we’re gonna also pass in the user
IDs but if you remember if you look at
the models chat we called it users so
we’re gonna assign users to user IDs and
we’re gonna call a weight on it and
assign it to a chat variable and once
that’s done we also need to update the
users now if you look at the user model
you’re gonna see that every user model
also has a list of chats in it so what
we need to do is we need to update this
property we need to basically push the
new chat ID to the array so what we need
to do
we need to do an update of all users
whose ID belongs to this user ID is
array so we need to call and update many
so the condition will be such that the
ID is inside of the range of user IDs so
what this is going to do is it’s going
to tailor the update query to all users
whose ID is in fact inside of the user
IDs array now the second argument is
where we’re gonna specify what needs to
be updated in this case we need to push
to the array so we can use the handy
push key and we’re gonna pass in an
object so this will be chat so this is
basically going to update the chats with
the newly created chat now we could have
also done chat dot undersquare ID or
just simply dot ID if you pass in the
entire object Mongoose is gonna be smart
enough to take out the ID out of that
object and only push in the ID property
to the array so we can leave it off like
that and finally we’re gonna do in a
wait on it and if everything went well we’re gonna return back the actual chat

Please follow and like us: