Default options
Set an option once for every operation, and let result types know about it.
Runtime defaults
defaultOptions on the Apollo Client instance applies to every operation of a given kind, so individual call sites only specify what differs:
import { InMemoryCache, provideApollo, withApolloOptions } from '@apollo-orbit/angular';
export function provideGraphQL() {
return provideApollo(
withApolloOptions(() => ({
cache: new InMemoryCache(),
link: /* ... */,
defaultOptions: {
watchQuery: { errorPolicy: 'all' },
query: { errorPolicy: 'all' },
mutate: { errorPolicy: 'all' }
}
}))
);
}
The three slots are independent. signal.query, signal.query.once and watchQuery all read the watchQuery slot — signal.query.once because it is built on watchQuery and reobserve. The query slot applies only to Apollo.query.
Declaring defaults to the type system
See Apollo's default-option declarations for the underlying type contract.
A runtime default alone does not change any types. errorPolicy decides whether a result carries data, an error, or both, so Orbit resolves result types against the default you declare:
import '@apollo/client';
declare module '@apollo/client' {
namespace ApolloClient {
namespace DeclareDefaultOptions {
interface WatchQuery { errorPolicy: 'all' }
interface Query { errorPolicy: 'all' }
interface Mutate { errorPolicy: 'all' }
}
}
}
Declare the same values you configured at runtime. Apollo Client requires the declaration whenever you set the runtime default, and reports it if you forget:
A default option for
mutate.errorPolicymust be declared inApolloClient.DeclareDefaultOptionsbefore usage.
With errorPolicy: 'all' declared, results widen the way the policy actually behaves: data becomes optional and error can be present:
const { data, error } = await this.addBookMutation.mutate({ variables: { book } });
// ^ TData | undefined
// ^ ErrorLike | undefined
Under the default of none, the same call rejects on failure and data is guaranteed:
const { data } = await this.addBookMutation.mutate({ variables: { book } });
// ^ TData
An explicit errorPolicy overrides the declared default. For signal operations, set it on the factory options; execute() and mutate() do not accept a new policy. fetchMore defaults independently to none, so pass its policy on the fetchMore call itself.
Signature style
Declaring any non-optional member of DeclareDefaultOptions switches Apollo Client's own methods and hooks from their classic signatures to their modern ones, application-wide. Modern signatures read declared defaults into their return types, but they infer types from the document and reject explicit type arguments:
this.apollo.client.query<Book>({ query }); // was fine, now a type error
this.apollo.client.query({ query: typed }); // inferred, and reads your declared defaults
Orbit's own APIs resolve declared defaults under either style and still accept explicit type arguments. apollo.cache and QueryObservable are unaffected.
The fix is to type the document rather than the call. See Codegen, which produces TypedDocumentNode documents that are correct under both styles.