How to Delete MongoDB Listing With GraphQL API

In this lesson, we'll use our custom server fetch() function to invoke the deleteListing mutation we have in our GraphQL API, to delete a listing in our listings collection.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL with a single-time purchase.

Thumbnail for the \newline course TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL
  • [00:00 - 00:20] With our custom server function, we've been able to query the listings field and by passing in a type variable, we've been able to type-define the data that is to be returned from our GraphQL request. Now, we'll look to see how we can make the GraphQL mutation in our API, the delete listing mutation.

    [00:21 - 00:39] In our server fetch function, we've specified that the request body has to have at the very least the query string that represents the GraphQL query we want to make. Though we've labeled this field as the request query, it can very well also be used for GraphQL mutations.

    [00:40 - 00:56] Our mutation, however, expects a variable argument to be passed in, which is the ID of the listing that is to be deleted. The JSON body we pass in expects a query field, which represents the GraphQL request we want to make, which is a string.

    [00:57 - 01:17] The other field we'll need to pass in is the variables field, which is an object for holding the variables that is to be passed into the GraphQL request. We'll define this variables field, but unlike the query field, this variables field will be optional, since not every GraphQL request will pass in variables.

    [01:18 - 01:29] We can denote this optional field by placing the question mark right after the property name. This specifies that this field could be defined or undefined.

    [01:30 - 01:50] Now, just like how the data of our request is to be typed, it'll be helpful if we're able to type define the expected variables of a request. So with that said, we'll make this interface a generic that expects a T-variables type with which will be the type of the variables field.

    [01:51 - 02:16] Where we use the body interface exists an error, since we're expected to pass the type of variable the interface is required to accept. Just like how we've introduced a T data type variable into our server fetch function, we can introduce a T variables type variable and give it a default value of any .

    [02:17 - 02:38] We'll then pass the T variables type value along to the body interface used as the type of the body arguments. Cool. We'll get a clearer understanding of why the capability of passing in a type of other variables is helpful when we construct our delete listing mutation.

    [02:39 - 03:02] Our server fetch function is prepared to allow components to make GraphQL mutations, so in the listings components, we'll follow the approach we've done before and create a call to action that will fire a mutation when clicked. We'll call this method delete listing, and the button text will be delete a listing.

    [03:03 - 03:18] Since our delete listing function will make an asynchronous request, we'll label the function as an async function. Here's where we'd want to call the server fetch function passing the expected GraphQL request and the variables of the request.

    [03:19 - 03:36] We'll first define the shape of both the data we expect to retrieve, as well as the shape of the variables we'd want to pass in. In the listings types file, we'll declare the expected types of the data and variables of our mutation as delete listing data and delete listing variables.

    [03:37 - 04:00] We'll take a quick peek at the GraphQL playground of our server API, we have our server running, and just so we can see the data being returned when we actually try to delete a listing. The data returned appears in a delete listing field, which contains all the properties of a particular listing.

    [04:01 - 04:20] We could have also verified this by just looking through the GraphQL Playground documentation, but this satisfies what we had in mind. We already have a listing interface defined in our types file, so we'll specify the delete listings data interface to have a delete listing field where its type is of listing.

    [04:21 - 04:45] The ID arguments we pass in is of type GraphQL ID in the back end, but this is a string of a client, so we'll define that as part of our delete listing variables interface. In the listings file, we'll import the newly created types for our new GraphQL requests.

    [04:46 - 04:56] We'll need to construct the query of our delete listing mutation. We'll set this query in a constant variable we'll call delete listing in capital letters.

    [04:57 - 05:07] We'll use the mutation keyword and declare the name of the mutation as delete listing. And we'll then call the delete listing mutation field itself.

    [05:08 - 05:23] In terms of the expected return, we'll just assume we only want the ID field of the deleted listing to be returned for now. Now we need to find a way to pass in the ID variable our request mutation expects.

    [05:24 - 05:33] What we've done in the playground so far is simply hard code the variable value . What we should do here is find a better way to pass the variable down.

    [05:34 - 05:51] In GraphQL, valuables are denoted with the dollar sign. So in the mutation declaration, we're saying we expect a variable of ID, and here we can also say the GraphQL type of this variable is GraphQL ID and is required.

    [05:52 - 06:05] As a note, keep in mind we're using the GraphQL schema language here. With the variable defined here, we can pass it down to the ID field the delete listing mutation expects.

    [06:06 - 06:20] With the mutation query available, we'll establish the server fetch function in our delete listing handler. We'll pass the delete listing data and delete listing variables type arguments.

    [06:21 - 06:36] We'll specify in the body of the request that the query is the mutation query we've set up, and the variables is to contain an ID. Let's retrieve an ID from the console when we query some listings.

    [06:37 - 06:50] We'll copy this one here and we'll place it as the ID for the listing we like to delete. Right after our fetch method, we'll place a console log to see what the data returned will look like.

    [06:51 - 07:06] Now, when we collect the delete listing button, in our console, we can see the ID information of the listing we just deleted, which tells us that our mutation was successful. If we attempt to query listings again, we can see that only a single listing remains.

    [07:07 - 07:23] Let's just pick this ID as well, place it in the ID variable of our mutation, and let's rerun and delete the listing once again. Perfect. At this moment, we have no more listings, which is why we've set up the seed script in our server to help with development.

    [07:24 - 07:54] We'll go to the terminal, run the seed script again, and when complete, in our UI, we'll be able to make our query and get all the listings back. A few remarks before we close, just like how we've appropriately introduced the ID variable for our delete listing mutation here, we can also do the same in GraphQL Playground.

    [07:55 - 08:07] The Playground actually offers a tab below, which gives us the capability to pass in variables. The other point we want to make is the benefit of type defining the variables in our request.

    [08:08 - 08:25] Since we've passed in the type variable of how the variables should appear for our delete listing mutation, if we try to introduce any other variable, we'll get an appropriate TypeScript warning, which is helpful. So when we pass in the data type, we're helping define the type of data being returned.

    [08:26 - 08:39] When we pass in the variables type, we help constrict the shape of variables this request expects. Since not every request needs variables, the variables field in our body request itself is optional.

    [08:40 - 08:41] You