1. 11
    Handle item deletions in Apollo using refetchQueries
    4m 16s

Handle item deletions in Apollo using refetchQueries

Rares Matei
InstructorRares Matei

Share this video with your friends

Send Tweet
Published 9 months ago
Updated 6 months ago

When making a mutation to delete an item in Apollo, there is no way to automatically mark that item as deleted based on the mutation return value. It cannot know how to update that were referencing that item now that it doesn't exist anymore. As a simple solution, we can use the refetchQueries option that the useMutation hook accepts, to tell Apollo which queries to refetch from the backend once the mutation has completed.

Instructor: [0:00] let's add the ability to delete notes you don't want anymore. I went ahead and just added a Delete button here. When I click it, it logs the ID of the note I clicked on. If we go back to my NotesList component, I added it here, below my View Note button component. It's currently just logging the ID of the note and the onClick Handler.

[0:29] Let's start writing out the deleteNote mutation. It's going to accept the note ID that I want deleted as the argument, and it's going to call the deleteNote mutation on our backend with our chosen note ID. I'll return the successful flag from it.

[0:47] Finally, like we did before, let's try to return the ID of the deleted note. Now, I'll destructure the deleteNote function from this. Instead of my console.log(), let's call it and pass it the deleted note ID variable.

[1:05] If we try this out and I try to delete the first note, I can see that it invokes a network call, but this note is still part of my list. If I look at what the mutation returned, and I open up the data, it did return successful. I do get the idea of my deleted note. If I refresh the page to reload my notes list, I can see that now it goes away.

[1:30] The changes are persisted on my backend, but the UI doesn't update when I click delete. When I return a note ID here, this only tells Apollo to update some field on this note reference in the cache. It has no idea we want to delete it from our notes query inside the cache.

[1:52] Returning the ID here of the note is useless in this case. What we'd have to do is instead, return the full notes list with the brand-new list of notes so Apollo can correctly update its contents in the cache. If I do this, I'd also have to pass all the note fields I want from it.

[2:12] I'd also have to make sure to pass in my category ID, which I then have to pass it to the mutation up here. Whoever invokes this also has to pass it in, which is going to be confusing and complex because other developers will think, "Why do I need to pass in a category ID when I want to delete a note?"

[2:30] Instead of this, Apollo gives us the option to refetch specific queries from the backend after our mutation has run. In my case, if I go back up here, I want to refetch a query by this name, GetAllNotes. I'll just add it to my list. This is one reason to give good names to your queries.

[2:55] What Apollo will do now, if my mutation is successful, it's going to trigger some follow-up calls to refetch all the queries I added in here. The nice thing is, by default, it will use the last known variables for the queries I pass through it.

[3:14] We don't have to worry about passing in a category ID because it's just going to reuse whatever we had selected in the drop-down. If I try this now and I click on Delete, we can see it disappears from the list and I do get two calls. The first one being my deleteNote mutation.

[3:34] The second one, it's actually my GetAllNotes query with my currently selected category all passed in. Because the backend had time to delete my note when I first made my mutation up here, when I make my second one, the list of notes will have already been updated.

[3:52] Now my state will be in sync with the backend. In summary, updating lists from mutations is a bit more nuanced and updating the cache automatically from them becomes a bit more complex. Instead, it's a lot more simple to just tell Apollo which queries to refetch once a mutation has run. It's smart enough to just reuse the last known variables for them.