Full Stack React — Part 7 (React, GraphQL, Express, MongoDB)

Episode 7: Create user resolver (evernote clone)

Photo by Sarah Dorweiler on Unsplash

In the previous episode, we created our note resolvers and more… check out the last episode if you missed it → Part 6

In this episode, we’ll create our user resolver and make the connections between our notes and users.

Agenda:

  • Create User resolver
  • UserCreator field on notes and created notes
  • Helper functions to get created notes array

Create User resolver

STEP 1: Make sure your server is up and running

STEP 2: Go inside your resolvers folder, then go to your user.js file. This is where you’ll write your user resolver code.

STEP 3: Let's go ahead and create the user resolver. Your user.js file should look like this →

// user.jsconst User = require('../models/users')module.exports = {
createUser: async({userInput}) {
const user = new User({
username: userInput.username,
email: userInput.email,
password: userInput.password
})
try{
const result = await user.save()
return { ...result._doc }
}
catch(err){
throw err
}
}
}

Explanation:

  • We named our resolver “createUser”
  • We created a user using our User Model, then store it in const user
  • In our try block we saved that user document in a const result and return that user document { ...result._doc }
  • In our catch block we pass in the err, and then throw err.

we are all set with creating users…

UserCreator field on notes and created notes

Now we need to head over to the notes resolver again, let’s focus on the notes resolver right now. In the notes resolver we are currently finding all the notes in our DB and returning them, we need to add something to our return

STEP 1: In our notes resolver add userCreator . As we discussed in previous episodes the userCreator specifies which user created this note. It should now look like this →

notes: async () =>{try {const Notes = await Note.find({})return Notes.map(note =>{return {...note._doc, userCreator: '5d28e81606fb7981dcfd0ee8')}})}catch(err){throw err}},

For testing purposes, we added the ID of a user from our DB. Therefore, every note we get back we can now query for the userCreator of that note as well. Which is “billy” in my DB.

However, even though we have the ID of that user, we wont get that user data back yet.

STEP 2: In our createNotes resolver, we also need to add the userCreator field. Which will b the same ID we used before, it should look like this now →

createNote: async ({noteInput}) =>{  const note = new Note({    title: noteInput.title,    content: noteInput.content,    image: noteInput.image,    userCreator: '5d28e81606fb7981dcfd0ee8' --> user that created note  })  let notes;  try {   const result = await note.save()   notes = {     ...result._doc   }   return notes  }catch (err){    throw err  }}

STEP 3: Now that we have the user, we need to push the notes we create to the user’s createdNotes array. This code will do that →

createNote: async ({noteInput}) =>{const note = new Note({title: noteInput.title,content: noteInput.content,image: noteInput.image,userCreator: '5d28e81606fb7981dcfd0ee8'})let notes;try {   const result = await note.save()   notes = {     ...result._doc    }   const findUser = await User.findById(5d28e81606fb7981dcfd0ee8)   if(!findUser) return new Error('User not found')   findUser.createdNotes.push(note)   await findUser.save()   return notes }catch (err){throw err}}

Explanation:

  • We find the user by ID and store that document in const findUser
  • If that user does not exist we throw an error. if(!findUser) return new Error(‘User not found’)
  • If they do exist, you have access to their data (user data) along with the createdNotes field. Now, you can push notes to their createdNotes array. findUser.createdNotes.push(note)
  • After this, save the user await findUser.save()

Overview: A note we create will have a default user attached “billy” by their ID. In order to push the note to the createdNotes array, we need to find that user first.

Helper functions to get user and created notes

STEP 1: Still inside the notes resolver file, above the module.exports create a method(function) called getUser and place the following code.

const getUser = async(userid) => {  try {    const userID = await User.findById(userid)    if(userID) return {...userID._doc}   }catch(err){     throw err    } }// module.exports {...}

Explanation:

  • This method takes a userid as param
  • We search the DB for this user by the userid we pass in, then store this document in const userID
  • If we find the user, return that user data (username, email, password, createdNotes) {...userID._doc}

STEP 2: Let’s create this getNotes method →

const getNotes = async(noteid) =>{  try{    const notesID = await Note.find({_id: {$in: noteid}})    return notesID.map(note =>{    return {...note._doc}   })  }catch(err){     throw err  }}// const getUser = () => {...}// module.exports = {...}

Explanation:

  • This method takes a noteid as param
  • In the try block , we find the note where the _id within the createdNotes array matches the noteid we pass in. const notesID = await Note.find({_id: {$in: noteid}})
  • We then loop through this document array and return the single document of the note. → return {…note._doc}
  • Lastly, in the catch block we handle the error by throwing it

STEP 3: Now we need to use these helper methods where we need them. In our notes resolver add this code.

notes: async () =>{try {const Notes = await Note.find({})return Notes.map(note =>{return {...note._doc, userCreator: getUser(note._doc.userCreator)}})}catch(err){throw err}}

Explanation:

  • Instead of returning just the ID of user in userCreator , we will call the getUser method that takes in an ID(same ID, which is user “billy”) as param and actually return the user data.
  • This method is ONLY called if we query for the userCreator of a note.
  • Catch block will handle the error (throw err)

STEP 4: Let’s do the same thing in the getUser method.

const getUser = async(userid) =>{try {const userID = await User.findById(userid)if(userID) return {...userID._doc, createdNotes: getNotes(userID._doc.createdNotes)}}catch(err){throw err}}

Explanation:

  • Since we want to query for the created notes associated with this user we must get these notes with the help from our getNotes method
  • we pass in the userID createdNotes array so that our getNotes can find the _id that matches a id in the array you passed in.

Be sure to test these queries out to make sure its working

Ex: When you query for notes, see if you can also query for userCreator you should now be able to get the user data back and you can query for their createdNotes if you want.

{
notes{
_id,
title,
userCreator{
username,
email
}
}}

If anything goes wrong try starting from scratch and empty out your collections (notes and users) and create a new user and replace the following fields with the userID. Then create note with this user and try querying again.

createNote: async ({noteInput}) =>{const note = new Note({title: noteInput.title,content: noteInput.content,image: noteInput.image,userCreator: 'userID you just created'})let notes;try {const result = await note.save()notes = {...result._doc}const findUser = await User.findById('userID you just created')if(!findUser) return new Error('User not found')findUser.createdNotes.push(note)await findUser.save()return notes}catch (err){throw err}}

That is all for this episode, if you guys have any questions please feel free to ask me :) I hope you guys enjoy…more to come

If you would like to watch the video, you can check it out here → Create user resolver and more

--

--

--

A passionate web developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

A Series of My Unfortunate Mistakes (When Writing Tests)

How an Angular App Work Behind The Scenes — Angular Flow

Part 1: Simple Ionic tutorial from scratch — From 0 to Live App

JavaScript React: Hooks

Runtime JSON type checks with Typescript interfaces

Securing APIs with AWS Amplify and Cognito

Angular 2 Data Binding

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

Ajea Smith

A passionate web developer

More from Medium

JS, Git & NoSQL

Why Should You Use Node JS ?

React and Redux simplified.

Create a nest js project from scratch (manually)

Learn Nest Js