Apollo-client: refetchQueries not working when using string array after mutation

Created on 8 Oct 2019  路  21Comments  路  Source: apollographql/apollo-client

Intended outcome:
After a create mutation, I want to refetch the list query to have the newly added item be displayed in the list, making use of the variables which the list query is run with previously.

As per the documentation, this should be doable:

Please note that if you call refetchQueries with an array of strings, then Apollo Client will look for any previously called queries that have the same names as the provided strings. It will then refetch those queries with their current variables.

Actual outcome:
When using the operation name as string in the refetchQueries array, no query is refetched, nothing is updated and no network activity is visible.

Versions

  System:
    OS: macOS Mojave 10.14.6
  Binaries:
    Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
    Yarn: 1.19.0 - /usr/local/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v10.16.3/bin/npm
  Browsers:
    Chrome: 77.0.3865.90
    Safari: 13.0.1
  npmPackages:
    @apollo/react-hooks: ^3.1.0 => 3.1.1
    apollo-cache-inmemory: ^1.6.3 => 1.6.3
    apollo-cache-persist: ^0.1.1 => 0.1.1
    apollo-client: ^2.6.4 => 2.6.4
    apollo-link: ^1.2.13 => 1.2.13
    apollo-link-context: ^1.0.19 => 1.0.19
    apollo-link-error: ^1.1.12 => 1.1.12
    apollo-link-http: ^1.5.16 => 1.5.16
    apollo-link-logger: ^1.2.3 => 1.2.3
    react-apollo: ^3.1.2 => 3.1.2

Most helpful comment

The whole purpose of using a string is that you should NOT have to provide the exact object as Apollo should automatically refetch the query with the current query variables.

All 21 comments

I had a similar problem but was resolved by providing the exact object used to fetch the query which may include any variables, query options and etc.

The whole purpose of using a string is that you should NOT have to provide the exact object as Apollo should automatically refetch the query with the current query variables.

Yeah I totally agree with you there man it sure is a bug or documentation is wrong. Didn't mean to sound like it ain't a bug. It's very inconvenient having to provide the exact same object especially multiple mutations in multiple places refetches the query.

I have a similar issue. The weird thing is that when I call a mutation where it deletes a row, and then I call the refetchQueries with a string, it actually works. But after I insert a new row, nothing happens when I do the refetch. It makes no sense because the delete is still a mutation, so I'm not sure what the difference could be. Both mutations return the same values. I'm looking at the network requests, and I see that after the insert there is no request, but after the delete, there is a new request that actually do re fetch

The only way I could make this to work is to change the fetch policy to cache-and-network

delete mutation
image

refetch
image

insert mutation
image

delete mutation hook
image

insert mutation hook
image

I have witnessed exactly the same behaviour! It works fine when I refetch after I delete an item but not when I create one.

Hi Friends, I have the same problem: refetchQueries works with update mutations, but nothing happens on insert mutations. Is there any known workaround?

Impacting us here also... 馃槴

Also running into this issue

I came accros this issue.
I create a new item from a modal, while the listing page is in the background.
After the mutation, I redirect to the detail page of the new item.
Also, when the mutation is completed, I can see the listing query is refetched (in browser dev-tools).
But the listing query result in the cache not getting updated.

If I cancel the redirect, which comes right after the mutation, there is no problem. After the query is refetched, cache gets updated.
If I keep the redirect, but make awaitRefetchQueries: true in the mutation options, there is no problem again.

I think, when the page that observes the query gets unmounted, even if the network request gets completed, cache can not be updated.

A cool way could be invalidating a query even if it wasn't observed by any active component.
Using this way, one could just tell the cache that the query result is now invalidated. And the first call to that query would be done by a network request. So, user creates a new record. Get redirected to the detail page of the new item. User may go to other pages, it doesn't matter. But when we come to the listing page again, we would trigger a network request, instead of showing the stale data in the cache.

This is just a simple idea of course. There may be positive/negative points about this.

Edit: After some thinking, I feel like using refetchQueries to refresh active queries and fetchPolicy: network-only for things like redirecting to listing pages might be much much more easy to implement and more maintainable. Using cache results is a very strong technique for things like infinite loaders, multiple isolated components which use the response from same query etc.

Most of the times I just don't feel it's ok to change the default fetchPolicy, but it is a good option to use for many use cases.

6017

I have witnessed exactly the same behaviour! It works fine when I refetch after I delete an item but not when I create one.

In case anyone is still interested, this behavior happens because when you delete something, the component holding the original query didn't get unmounted (normally because you just show a popup), while when creating a new item you redirect to another screen (i.e. create item page) unmounting the page holding the original query.

Apollo maintains a list of observable queries at any given time, which is based on which components are currently mounted that defined a query (i.e. through <Query>...</Query> or useQuery). When a component gets unmounted - at least in the React world - , Apollo removes it from the list of observable queries by calling QueryManager.tearDownQuery when the component unmounts. During refetchQueries , when given a Query name string, apollo searches only the observable queries and because it can't find it, it doesn't execute a refeetch. If you provide a { query: ..., variables: .. } as a refetch value, Apollo bypasses this search and always executes the query you've given it, as if it was a completely new query (since it has the doc and the variables it needs to execute it)

I don't know if @hwillson would like to give us more context as to whether there is a way around this (except from not using the React or by making sure that we unmount as little as possible on crucial refetches).

In short:

refetchQueries will only work with strings if the component that defined the original query is not unmounted. On the contrary, it will always work when using the { query... , variables: ... } style.

So it's not possible to perform a refetch with the original query and variables? Doesn't sound to me a good choice :/

So it's not possible to perform a refetch with the original query and variables? Doesn't sound to me a good choice :/

It's only possible if you don't navigate away (i.e. unmount the component that performed the original query).

Your other option (which is not actually a solution) is to use a different networkPolicy so that when you revisit the component that held the query, a server-query is performed.

I see; thanks!

@3nvi

refetchQueries will only work with strings if the component that defined the original query is not unmounted.

I have three components render on the same page which use the same query(and same operation name) but difference variables.
when I specify operationName as refetchQueries, only the last one got refetch.
Why?

cause it literally does just that. It refetches the query with the latest variables. From apollo's side it's only 1 query with 3 different invocations, so i tries to refetch the "latest" invocation.

Still an issue in 3.1.5 on May 22nd 2020.
This is an important feature, frequently used, that should be fixed

What happened with this issue, please!!

I think this needs to have option to refetch non observable queries.
and also not latest varibales - but all variables for this query

those flags can solve a lot of issues

Apollo client 3.2.5 and issue is not fixed. Any updates?

May be related to #3540

Was this page helpful?
0 / 5 - 0 ratings