Urql cache invalidate is not removing items from the cache

Viewed 350

My application has a list of organizations and I have buttons in my UI to delete them individually.

I would like the list to update and remove the deleted organization but that is not working for me.

I have set up a cache exchange like this, where I have (redundantly) tried two cache invalidation methods from the Urql docs:

const cache = cacheExchange({
    updates: {
        Mutation: {
            delOrg(_result, args, cache, _info) {

                // Invalidate cache based on type
                cache.invalidate({ __typename: 'Org', id: args.id as number });

                // Invalidate all fields
                const key = 'Query';
                cache
                    .inspectFields(key)
                    .filter((field) => field.fieldName === 'allOrgs')
                    .forEach((field) => {
                        cache.invalidate(key, field.fieldKey);
                    });
            }
        }
    }
});

The GraphQL query that returns the list of organizations looks like:

query AllOrgs {
    allOrgs {
        id
        name
        logo {
            id
            url
        }
    }
}

And the mutation to delete an organization looks like: (it returns a boolean)

mutation DelOrg($id: ID!) {
    delOrg(id: $id)
}

cache.invalidate does not appear to do anything. I have checked the cache using the debugging plugin as well as console.log. I can see the records in the cache and they don't get removed.

I am using

"@urql/exchange-graphcache": "^4.4.1",
"@urql/svelte": "^1.3.3",
1 Answers

I found a way around my issue. I now use cache.updateQuery to update data rather than a single line, I now have -

updates: {
        Mutation: {
            delOrg(_result, args, cache, _info) {
                if (_result.delOrg) {
                    cache.updateQuery(
                        {
                            query: QUERY_ALL_ORGS
                        },

                        (data) => {
                            data = {
                                ...data,
                                allOrgs: data.allOrgs.filter((n) => n.id !== args.id)
                            };
                            return data;
                        }
                    );
                }
            }
        }
    }
Related