1. 14
    Evict deleted items from the Apollo cache
    4m 9s

Evict deleted items from the Apollo cache

Rares Matei
InstructorRares Matei

Share this video with your friends

Send Tweet
Published 9 months ago
Updated 6 months ago

When deleting an item, we express our intent to completely remove all traces of it. If the mutation succeeds, that means it's gone from the backend as well. But some components external to our note list, might still be listening to our deleted item. To ensure they get the update, we can completely evict the normalised instance from the cache using the cache.evict() method.

Instructor: [0:00] At the moment, whenever we invoke the deleteNote mutation, we're just filtering out that note from the notes query. That's why our list can update.

[0:10] Let's have a look at what actually happens in the Apollo cache. If I click on ROOT_QUERY here and then I open up my list of notes to the right, and I can see the first note in that list is a reference to the full note object with ID 1, that is down here. We can see the full note data, including the content.

[0:31] Now, if I go back to my list of notes, and I delete the first note, I can see that it correctly disappears from here. Now we have only five items instead of six. The first one is now a reference to the second note. That full first note still remains here with all its content.

[0:50] Sometimes that can be fine, and it might be exactly what we want. Many notes apps allow you to just filter lists, based on an owner maybe, which means only temporarily hiding certain items. In this case, we've completely deleted this note on the backend.

[1:05] We want to remove all traces of it on the frontend as well. An example of how this problem might manifest on the UI is if I open up another note, just to edit it, this component on the right here is now listening to the full note reference with ID 2.

[1:21] If I delete that note from the list, it disappears from the list, but this component doesn't know about that and it still allows me to edit it as if it's still there. After we filter the note from the list, we can also evict it from the cache completely by passing in the ID of the item that we want removed.

[1:41] This is all we need to do. If we look at our edit note component that displays the full note, it is querying a note by ID. Also if we go down here and look at its UI component, we can see that it can handle null inputs, and displays this not found message if a certain note isn't found.

[2:01] This is an important state we want to handle in this case. Now if I go back to the browser and I have the devtools open, we now have only four items in the list. The first one is a reference to the node with ID 3, which is in here in the cache. Watch this space here.

[2:17] Let's see what happens if I delete the first note in the list. We can see that its full, normalized instance completely disappeared from the cache now. If we look at the notes list, it only has three references left.

[2:32] If I close this, open up the first note and then try to delete it, the full edit note component on the right is going to update to tell us, "Hey, I couldn't find the note by that idea anymore. Are you sure it exists?"

[2:45] If we open up the devtools and I go to the cache and I look at the root query, I can see that yeah, there is a note query here. It is trying to reference a note with ID 4, but it's not in the cache. Anyone listening to this query will get a NULL item back.

[3:04] Besides doing this to keep our local cache in sync with the backend, we're also making sure that whenever we delete a note, other parts of the UI update to reflect this new state. Since we can edit queries like notes, why not blank out the note query as well?

[3:24] If we do this, we'd be coupling our notes list component to the single note query, which is something this component isn't really concerned about. We don't really want to bother with this.

[3:34] To summarize, when deleting items, we're making sure here to only update local queries so as to not couple this component with anything else. I'm filtering out the deleted items from the list so the component can correctly update with the new list length.

[3:53] Then, because it's a complete deletion of this note from the backend, we're also expressing our intent to evict it from the whole cache, which will have the added benefit of making any other components in our React tree update accordingly.