We will have our queries only hit get endpoints, and have the ability to delete and update players for our React Native, and React app.

Image for post
Image for post
Photo by Vishnu R Nair on Unsplash

We will update our graphql server to get a specific player, update a specific player, and delete a specific player based on that player’s id. We will then connect to our apollo-client, and have all of our queries hit get endpoints to make it more developer friendly. .

If you did not do the previous parts of this tutorial I would recommend you to do those parts before doing this tutorial.

Now let’s start building our back end to get a specific player, update a specific player and delete a specific player.

Since the back end will be the same for both our react native, and react app we will just create the back end for both apps in one go.

First we will update our our Player object type to retrieve an id from our mongodb database. Since we will use it to route to the Player screen/page, and use that same id to retrieve that player’s data.

Update your Player object type.

Now query your Player object type by id to check if it’s working using our already made query.

Image for post
Image for post

Now we should see all of our player’s id.

Great! Let’s start defining our resolver and our type definitions for our getPlayer query that will take an argument of id of type string.

First the typeDefs.js file.

Add our getPlayer Query.

Alter the resolver file to get that specified Player using the model’s findById method. Our field will contain our context, info, and obj in a private variable, and our args as a second argument. The difference between this field from our createPlayer, and player fields is that it will contain asynchronous code which would be the callback of the findById method. It will stop execution until we retrieve data for that specified player, and returns that player. We will follow the same pattern for our updatePlayer field as well.

Define your getPlayer field.

Now we should get a player based on it’s id.

Image for post
Image for post
Result of getting our specified player.

Awesome, now we will work on mutating our data. Let’s define our updatePlayer field. Our updatePlayer field will take nullable arguments such as id, name, position, team, jerseyNumber, and wonSuperBowl, and it will return a Player object type which is our updated player.

Define updatePlayer field

In our resolver it will be the similar to our getPlayer field, this field will also contain asynchronous code, and will return the updatedPlayer once it has data.The context, obj, and info will be in a private variable, and we will be using the args.id for the model’s findByIdAndUpdate method, passing a object with _id as the key and id as the value.

Define updatePlayer resolver field.

Now when you update a player it should return the updated player with one field updated, and all fields updated if you were to update all fields.

Image for post
Image for post
Image for post
Image for post
Result of updatePlayer resolver and type definition

We are almost finished with the back end. We just now need to define our deletePlayer field which will just take an id, and will return a nullable, but since in graphql there is not null return type we will use a Player object type. Because when we delete a player we would just redirect the user to the player’s list page/screen. Therefore don’t need to return a player. So for our type definition we will take an arg of id of type String.

Define a deletePlayer field.

Now the deletePlayer will be similar to the createPlayer field , and the players field. It will not contain asynchronous code since we are performing an empty return. The context, obj, and info will be in a private variable, and we will be using the args.id for the model’s findByIdAndDelete method, passing a object with _id as the key and id as the value.

Define delete resolver.

When you delete a specific player it will return null, and in our getPlayer query using that same id it should also return null since it does not exist. You can add a check to throw an error is it not found in the database but that is it for the back end.

Image for post
Image for post
Image for post
Image for post
Result of deletePlayer resolver and type definition

Congratulations! You have a full graphql rest api if you did the previous two tutorials. If you didn’t then you know how to get a specific player, delete a specific player, and update a specific player based on their id’s. Now we will start on the react native app first. If you want to start on the react app instead of the react-native app skip this part of the tutorial.

We will start defining our mutations for our react native app that will update and delete players, but before that let’s make our http response’s more readable for error handling with the react-native debugger. Let’s set all queries since they are responsible for retrieving data to a GET requests instead of POST requests. Go to your HttpLink instance in your index.js and add a useGetForQueries property then set it true.

Add a useGetForQueries property to your HttpLink instance for your Apollo Client.

So for getting a specific player we will create a Player component which hold all it’s information, and we will also be updated in real time using our updatePlayer mutation and optimistic responses. Also from that component we can delete a player, and when it’s deleted it will redirect the user to the Player’s list component. We will first create our Player component which will only retrieve data. Also define styles for the text of the component underneath the component. We will add a fetchPolicy of network-and-cache to player’s list and player component.

Define a Player component responsible for retrieving data for now.
Add a fetchPolicy of network-and-cache to player’s list component.

Now we will import our Player component to our Navigator.js file. Also import createStackNavigator for creating nested routes. Have it’s initial route be the Player’s list, and have it’s back button display. Replace the player’s list component with the player’s list stack navigator.

Import your Player component, and define nested routes.

Now alter your Player’s list component, so you would get the id from your players query. When you render each individual item pass your id to redirect to the Player component, and pass the id to get data for the current player.

Alter the query to also retrieve the player’s id.
Alter your method for rendering each individual item so your can redirect to the Player component.

Now your Player component should be able to be displayed.

Now we will finish this tutorial, and import the Mutation component for our mutations. We will define our update player mutation which we will define variables for each argument of the mutation, and return the same fields as the query we defined earlier. Then we will define the deletePlayer mutation which will take a id argument, and it doesn’t matter what it returns since we are redirecting the user.

But we will add a fetchPolicy of network-and-cache for our query getting the our player, and our list of players. Why? Well by default graphql is cache-first which means it will retrieve data from our cache first it there is an existing query. When dealing with updating data it is best to use network-and-cache which make an api call if the data from the api call is different then the cached query it will update the query and display the updated results.

Define mutations to your Player component.

We will start editing our Player component, first off we will add 6 values to your state.

returnedPlayer-Will be used to get the updated player from the optimistic response, then update the UI.

updatedPlayerName-update name value.

updatedPlayerPosition-update position value.

updatedPlayerTeam-update team value.

updatedPlayerJerseyNumber-update jersey number value.

updateWonSuperBowl-update won superbowl boolean value.

Then we will add 2 functions to our component which are updatePlayerFunc, and deletePlayerFunc. Both functions will be asynchronous and take a function as an argument, then we will use that function to manipulate our graphql server because these functions will be our mutations returned from our Mutation component callback.

Then in our updatePlayerFunc we will assign our values needed for updated player to a variable which would be used as a variable for the mutation. Then we will destruct the data variable since our arguments for the updatePlayer mutation are nullable. Then the data retrieved from the mutation will set the state of the returnedPlayer, and also reset the state of our update values since we are finish updating the player.

Add a updatePlayerFunc and deletePlayerFunc

Then in the UI we will conditionally render each property(except the wonSuperBowl) of the returnedPlayer state if the property is truthy. For the wonSuperBowl property we will use the returnedPlayer state if the wonSuperBowl property is truthy or use the query response instead to indicate if that specific player won a super bowl or not.

We will start defining our mutations for our react app that will update and delete players, but before that let’s make our http response’s more readable for error handling. Let’s set all queries since they are responsible for retrieving data to a GET requests instead of POST requests. Go to your HttpLink instance in your index.js and add a useGetForQueries property then set it true.

Add useGetForQueries for using queries for only get requests.

So for getting a specific player we will create a Player component which hold all it’s information, and we will also be updated in real time using our updatePlayer mutation. Also from that component we can delete a player, and when it’s deleted it will redirect the user to the Player’s list component. We will first create our Player component which for now will retrieve data for that specific player.

Define your Player component for retrieving queries.

Import your styles which we would define later, which is specifically the UpdatePlayer.css. We will define a query for getting a specific player using a id variable of type string. Then we will alias our query to make it more user readable, and alias to player, since we are getting a specific player. Then we will have a div and a Query component. Then in the query component children callback if there is data returned return html that returns the specific player’s info.

Then define your UpdatePlayer.css just copy and paste this code since this is irrelevant to the topic of this tutorial.

Define your styles for your UpdatePlayer.css.

We define styles for your update container, delete button, yes, no button, and the container for those buttons(yes, no) in css classes.

Then add a Player component to your routes.

Import your Player component to your Router.

Our route will have a id parameter for your Player component.

Now we will go back to our Player’s list component. Then we will edit our query to retrieve a player based on it’s id also so we can use that id for our onClick event for each individual player item. We will then edit our render method that will be responsible for rendering each individual player item. Then we will add a onClick which will redirect to the players/player’s id route.

Edit your .map to redirect to each item to each corresponding Player.
Image for post
Image for post
Result of getting specific player.

Now we will finish this tutorial, and import the Mutation component for our mutations. We will define our update player mutation which we will define variables for each argument of the mutation, and return the same fields as the query we defined earlier. Then we will define the deletePlayer mutation which will take a id argument, and it doesn’t matter what it returns since we are redirecting the user.

Define your mutations for update, and delete for your react app.

Now we will start editing our Player component, first off we will add 6 values to your state.

showEditForm-boolean value responsible for showing the edit form.

updatedPlayerName-update name value.

updatedPlayerPosition-update position value.

updatedPlayerTeam-update team value.

updatedPlayerJerseyNumber-update jersey number value.

updateWonSuperBowl-update won superbowl boolean value.

Then we will add 2 functions to our component which are updatePlayerFunc, and deletePlayerFunc. Both functions will be asynchronous and take a function as an argument, then we will use that function to manipulate our graphql server because these functions will be our mutations returned from our Mutation component callback.

Then in our updatePlayerFunc we will assign our values needed for updated player to a variable which would be used as a variable for the mutation. Then loop through variable, and delete empty values, and values that are not boolean. Then refresh the page and retrieve our updated data and it should display the updated player data. If you saw the react-native tutorial you can also use a optimistic response.

Then in the deletePlayerFunc retrieve the player’s id from your route params. Then use that same id to delete the specified player. Afterwards redirect to the Player’s list component.

Define your updatePlayerFunc, and deletePlayerFunc for your Player component.

Now we will define our render method, which will render our updated form within a div within our update-container class within our Query callback’s return statement. Then below our Query component have two mutation component’s which will return the button’s for deleting and updating a player. We will then show our form based on our doEditForm value which is initiated by our button returned with our update mutation component.

Finish off your Player component.

Now your Player component should look like this.

Image for post
Image for post
Image for post
Image for post
Update Player result.

And after you delete it you should not see that player in your PlayersList component.

Image for post
Image for post
Delete Player result.

Congrats you build a full rest app using apollo and graphql, they are many things you can improve from this current source code, but I wanted to make sure we did not go off topic of this tutorial.

Here is the current source code to use for reference.

For React App:

For React Native App:

Happy Coding.

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