apollo-client: defaultOptions do not work

I tried setting defaultOptions like this:

export const apolloClient = new ApolloClient({
  link,
  cache,
  connectToDevTools: true,
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'cache-and-network'
    },
    query: {
      fetchPolicy: 'cache-and-network'
    }
  }
})

and yet re-rendering of components does not trigger refetching, however manually setting fetchPolicy option on a particular component does achieve the intended result

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 32
  • Comments: 43 (5 by maintainers)

Most upvoted comments

Okay, guys, I think the reason is you should provide all 3 properties together (watchQuery, query and mutate):

This code works

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'ignore',
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
  mutate: {
    errorPolicy: 'all'
  }
}

This code doesn’t affect to default options:

const defaultOptions = {
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
  mutate: {
    errorPolicy: 'all'
  }
}

or…

const defaultOptions = {
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  }
}

@helios1138 @stefanholzapfel @sfilipov @hwillson please check it. It works for me.

You have to declare defaultOptions as a constant like this:

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'all',
  },
  query: {
    fetchPolicy: 'cache-and-network',
    errorPolicy: 'all',
  },
  mutate: {
    errorPolicy: 'all',
  }
}

const client = new ApolloClient({
  link: from([
    logoutLink,
    errorsLink,
    httpLink
  ]),
  cache: new InMemoryCache(),
  defaultOptions
});

are default props that hard to fix? its been 1 year and 1 day lol.

@kcvin94 It sounds very easy for you to fix them. Mind send a PR?

Hi 😃 The issue is still the same in the latest versions:

"@apollo/react-hooks": "3.1.2",
"apollo-boost": "0.4.4",

The following does successfully use network-only:

defaultOptions = {
    watchQuery: { fetchPolicy: 'network-only', errorPolicy: 'all' },
    query: { fetchPolicy: 'network-only', errorPolicy: 'all' },
    mutate: { errorPolicy: 'all' },
}

This (which would be much nicer) does not work and uses the cache:

defaultOptions = {
    query: { fetchPolicy: 'network-only' },
}

This should be fixed thanks to #9210 in @apollo/client@3.5.7 (published earlier today)!

4 years later its still broken with latest apollo client.

I’m seeing the same issue with network-only as well.

If I use the following defaultOptions, the cache still seems to be in effect:

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
  mutate: {
    errorPolicy: 'all',
  },
};

However if I supply fetchPolicy: 'network-only' as an option to an individual query, the cache is not used (as expected).

Still have the same issue:

@apollo/client”: “3.0.0-beta.43”

React client side app

const client = new ApolloClient({
  link: concat(authMiddleware, httpLink),
  cache: new InMemoryCache(),
  defaultOptions: {
    watchQuery: { errorPolicy: "all" },
    mutate: { errorPolicy: "all" },
    query: { errorPolicy: "all" },
  },
})

Default options not working

If if provide errorPolicy to the useMutation hook, then it works?

@daryn-k it seems that when we mean to set fetchPolicy for queries, we actually need to set watchQuery.fetchPolicy. I think it’s a bit confusing and should be described better in the documentation, but it works (at least on the latest version of Apollo Client).

And in this case, I’m not sure what query.fetchPolicy is supposed to be about

My config currently just contains

defaultOptions: {
  watchQuery: { fetchPolicy: 'cache-and-network' },
},

@jbaxleyiii is it possible to get some updates on this?

Still a huge issue here - I’m not sure why it’s closed when the supposed fix hasn’t even been merged yet as well ???

so looking at the code with the latest release useQuery will eventually call the following function which will merge the option passed to useQuery with the default options

ApolloClient.prototype.watchQuery = function (options) {
  if (this.defaultOptions.watchQuery) {
    options = mergeOptions(this.defaultOptions.watchQuery, options);
  }
  if (this.disableNetworkFetches && (options.fetchPolicy === 'network-only' || options.fetchPolicy === 'cache-and-network')) {
    options = __assign(__assign({}, options), { fetchPolicy: 'cache-first' });
  }
  return this.queryManager.watchQuery(options);
};

the issue here is that if you don’t define fetchPolicy in your options when you call useQuery it defaults to cache-first which then overwrites the default options on mergeOptions as shown above the default value of cacheFirst is being set in createWatchQueryOptions

...
else if (!watchQueryOptions.fetchPolicy) {
  watchQueryOptions.fetchPolicy = 'cache-first';
}
...

It’s possible this PR introduced the error.

https://github.com/apollographql/apollo-client/pull/5863/files

From what I can tell, if you do not define an errorPolicy on the mutation itself, then an object with

{
   errorPolicy: undefined
}

gets passed in here (line 101 of MutationData.ts): https://github.com/apollographql/apollo-client/pull/5863/files#diff-93aa5dbc2696fb1257210a16aeac6e82L101

In ApolloClient, it will merge errorPolicy: undefined with the default errorPolicy set on ApolloClient, effectively wiping out the top-level default:

ie. options passed to this function will be { ..., errorPolicy: undefined, ... }

ApolloClient.prototype.mutate = function (options) {
        if (this.defaultOptions.mutate) {
            options = __assign(__assign({}, this.defaultOptions.mutate), options);
        }
        return this.queryManager.mutate(options);
    };

cc: @jbaxleyiii

@hwillson in terms of reproduction steps, I’d need to sanitise some of the production code we have, but long story short, when we try to do something like the following, it doesn’t work for us - the cache is used:

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'ignore',
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all',
  },
}

const apollo = new ApolloClient({
  defaultOptions,
  // I tried either initialising a cache like this:
  // cache: new InMemoryCache(),
  // or not defining the cache key on the object. Both don't work for me
  uri: '/graphql/',
})

// then try to run a query directly using the apollo client
// it does not do a new network request
// instead it uses the cache
const entity_id = 1
apollo.query({
  query: load_some_info_query,
  variables: { entity_id },
})

// it is possible to force a network request if fetchPolicy is set on each query
apollo.query({
  query: load_some_info_query,
  variables: { entity_id },
  fetchPolicy: 'network-only',
})

apollo-client version: 2.4.0 node version 8.11.3

There seems to be an issue with the constructor. A “fix” is to assign the client.defaultOptions after the ApolloClient is created:

	const client = new ApolloClient({
		credentials: 'include',
	})

	client.defaultOptions = {
		watchQuery: {
			fetchPolicy: 'network-only',
		},
	}