Graphql-flutter: Updating a list's cache after a mutation

Created on 4 May 2020  路  5Comments  路  Source: zino-app/graphql-flutter

Hi! I'm using this package to write a Flutter app and I'm really liking it so far.

I have a question about cache. I'm using an OptimisticCache.
I have a screen which displays a list of the results coming from this query

query {
  items {
    __typename
    id
    name
  }
}

Somewhere else in the code I can perform a mutation

mutation($name: String!) {
  insert_item(object: {
    name: $name
  }) {
    __typename
    id
    name
  }
}

When I do, everything works perfectly and without errors, and the list's query is correctly triggered again.
It gets its data from the cache, but the newly inserted item is not in the cache.

I can't update the cache directly as the list of items does not have a key that I can use (am I wrong?) but I would really like to avoid refetching the data.

Is there a way to add the new item to the query's cache?

Thanks.

Most helpful comment

Absolutely, here is how I solved it:

Mutation(
  options: MutationOptions(
    documentNode: gql(<my mutation>),
    update: (cache, result) {
      final key = QueryOptions(
        documentNode: gql(<my list query>),
      ).toKey();

      final newElement = result.data['item'];

      final data = cache.read(key);
      final List items = data['items']
        ..insert(0, newElement);

      data['items'] = items;

      cache.write(key, data);
    }
  )
)

I was not able to update items directly inside data (probably because it is a LazyCacheMap?) so I cloned the items to a new list and then reassigned it to the data map.

Hope this will be useful in the future!

All 5 comments

You can try to read the list of objects related to query by operation key
https://github.com/zino-app/graphql-flutter/issues/57#issuecomment-523035356

Than you need to add cache entry on the inserted item and update the list of items under operation key)

I did not tried this personally as far as I have paginated list...
But I looked a lot through the the cache structure)

Thank you, that worked nicely for me! From what I can see the v4 roadmap (#608) plans to remove the LazyCacheMap and make this process even easier.

I'm closing this issue now, thanks again @vasilich6107

Could you share your code snippet here so other could benefit from this issue?

Absolutely, here is how I solved it:

Mutation(
  options: MutationOptions(
    documentNode: gql(<my mutation>),
    update: (cache, result) {
      final key = QueryOptions(
        documentNode: gql(<my list query>),
      ).toKey();

      final newElement = result.data['item'];

      final data = cache.read(key);
      final List items = data['items']
        ..insert(0, newElement);

      data['items'] = items;

      cache.write(key, data);
    }
  )
)

I was not able to update items directly inside data (probably because it is a LazyCacheMap?) so I cloned the items to a new list and then reassigned it to the data map.

Hope this will be useful in the future!

@emilioschepis it is definitely useful for me.
I couldn't find an example in the docs so I was looking for an example code on how to insert into cache.
I think this example should be in the docs!

Was this page helpful?
0 / 5 - 0 ratings