gql-dart / ferry

Stream-based strongly typed GraphQL client for Dart
https://ferrygraphql.com/
MIT License
604 stars 116 forks source link

Update an item to list after mutation #352

Open minhnguyenandpad opened 2 years ago

minhnguyenandpad commented 2 years ago

Hi can someone have an example of mutation of adding an item to a list. I don't know how to update the list after call the mutation

MbeleLebohang-uct commented 2 years ago

I had a similar problem recently and I looked at how Apollo does it and I implemented it for ferry.

The solution I implemented is quite length, but the gist of it is that:

Using StateManagement, I extended the ferry client to keep track of all the requestIds and their operationRequest object. This way I can use the requestController on the client to refetch the operations as outlined on ferry docs here.

Disclaimer: This is just an idea, hopefully, it will solve your problem for now. Most probably not that efficient either.

See this link for apollo refetchQueries on mutations

minhnguyenandpad commented 2 years ago

Thanks you for your answer. But in the future the docs will contain more examples.

knaeckeKami commented 2 years ago

See https://ferrygraphql.com/docs/mutations#updating-the-cache

One way to solve this is to use updateCacheHandlerKey.

Add a const string

  static const addItemToListKey = 'addItemToList';

Then, set

updateCacheHandlerKey = addItemToListKey;

in your mutation request object (if your mutation has the name FetchItem, use something like

GFetchItemReq((b) => b
  ..updateCacheHandlerKey = addItemToListKey
  ..<rest of mutation params>
);

In the constructor of your Client(), pass

  updateCacheHandlers: {
        addItemToListKey:  addItemToListCacheHandler
  },

with

void addItemToListCacheHandler(
  CacheProxy proxy,
  OperationResponse response,
) {
  // do whatever you want with the cache here, for example:

 //get the item from the response
 final updatedItem =  response.data as <Your response type here>? ;

 //get the old item list
 final listRequest = GMyItemListReq();
 final oldResult =   proxy.readQuery(listRequest);

 // add the item to the list
 final newList = oldResult.rebuild(b) => b..list.add(updatedItem);
 proxy.writeQuery(listRequest,  newList);
}

With cacheHandlers, you can do arbitrary updates to the cache on every response, and if you have listeners to any of the queries with are affected by updates to, the will receive new data.

You could also call client cache.writeQuery or cache.writeFragment directly after doing the mutation (but using the cachehandlers is more scalable and less error-prone)