1

I'm having a hard time figuring out how to update a list of items (in the cache). When a new item is created with react-apollo.

The <CreateItemButton /> component is (in my case) not nested within <ListItems /> component. From what I can figure out, I need to update the cache via the update function in my createItemButton <Mutation /> component.

The problem is when I try to store.readQuery({query: GET_LIST_ITEMS, variables: ???}) to get the current list of items (to append my recently created item), this can have variables/filters (for pagination, sorting etc.).

How do I know what variable to pass to the store.readQuery function, is there a sort of "last used variables" around this, or do you have any other suggestion on how to solve this issue?

webbm
  • 634
  • 8
  • 18
Michael Falck Wedelgård
  • 2,943
  • 1
  • 27
  • 39
  • 2
    I suggest adding code snippets and examples. Perhaps a link to a demo/example that people can use to help answer your question. (https://stackoverflow.com/questions/21285923/reactjs-two-components-communicating?rq=1) might help. But examples and code snippets are best practice when asking on SO. – nstanard Feb 04 '19 at 18:53

3 Answers3

2

This is a known Apollo issue and the team is working on it. The current options you have can be found in this medium post.

It is also an issue with deleting/updating an item when you have it in a list with filters or pagination.

Here is a reference of an opened issue on Github about it

Sam Uherek
  • 293
  • 1
  • 5
0

This seems to work, but a bit hacky to access the cache.watches Set? :S

The trick is to access the cache's variables for a given query, save it and perform a refetch with the given query variables. In my case after creation of an item:

export const getGraphqlCacheVariables = (queryName, cache) => {
  if (cache.watches) {
    const watch = [...cache.watches].find(w => !!w.query[queryName]);

    if (watch) {
      return watch.variables;
    }
  }
};

The mutation update function:

let variables;

const update = (cache, { data }) => {
  if (data && data.createTask && data.createTask.task) {
    variables = getGraphqlCacheVariables('GetTasks', cache);
  }
}

And the refetchQueries function:

const refetchQueries = () => {
      if (variables && Object.keys(variables).length > 0) {
        return [{ query: GET_TASKS, variables }];
      }
      return [];
}

Bot the update and refetchQueries functions should have access to the variables variable

The benefit compared to the solution in the Medium article, is that you're not deleting the cached data for a given query (GET_TASKS) with different variables.

Michael Falck Wedelgård
  • 2,943
  • 1
  • 27
  • 39
0

Apollo now provides a new directive that allows ignoring of some variables when querying the cache. Check it here. I've used it to ignore my changing pagination params.

kimobrian254
  • 557
  • 3
  • 10