Does `cache.evict` really automatically remove dangling references from arrays in the cache?

The cache eviction documentation includes this section:

Filtering dangling references out of a cached array field (like the Deity.offspring example above) is so common that Apollo Client performs this filtering automatically for array fields that don’t define a read function. You can define a read function to override this behavior.

Does this actually happen? I’ve just tried it, and it’s not happening for me, and looking through the source code, there seems to be nothing there that suggests it should happen. Simple example as I understand it should work:

The cache contents:

{
    ROOT_QUERY: {
        __typename: 'Query',
        todos: [{
            __ref: 'Todo:123'
        }]
    },
    'Todo:123': {
        __typename: 'Todo',
        id: '123',
        title: 'Buy groceries'
    }
}

The cache eviction:

cache.evict({ id: 'Todo:123' });

The cache contents after eviction:

{
    ROOT_QUERY: {
        __typename: 'Query',
        todos: [{
            __ref: 'Todo:123'
        }]
    }
}

What I would expect according to the documentation:

{
    ROOT_QUERY: {
        __typename: 'Query',
        todos: []
    }
}

The weirdest thing is, I remember it working, but I’m really not sure anymore.

@hwillson @StephenBarlow Do you guys happen to have any insights for me on this? I’d be super grateful!

Hello, good question! The cache state you show is in fact correct (and the documentation note that you reference is ambiguous, my bad :grinning_face_with_smiling_eyes:).

By default when you evict an object (such as Todo:123), references to it in your cache are not removed. These references becomes dangling references, meaning they point to a nonexistent object. These references remain in case the object is subsequently restored.

The filtering described in the documentation happens specifically when you query a cached list field that includes one or more dangling references. In the example above, if you execute a query for todos, it will return an empty list because it automatically filters out the single object (because it’s a dangling reference).

All of which is to say, even though the cached list’s contents include the dangling reference, query results for that list shouldn’t.

2 Likes

Thank you, @StephenBarlow! That makes a lot of sense and explains what seemed like a discrepancy with the first paragraph in the dangling references section of the docs.

2 Likes