apollo-client
apollo-client copied to clipboard
Typings do not indicate that data can be {} in some cases
I noticed that in some cases client.query
and client.watchQuery
will return data: {}
- using
client.query
with fetch-policycache-only
, but cache does not contain the requested query - using
client.watchQuery
with fetch-policycache-only
orcache-and-network
, but cache does not contain the requested query - using
client.watchQuery
and then removing the requested query from cache usingcache.modify
.
When using the schema and query below, client:codegen
will create the following types:
schema.graphql
type Entry {
id: String!
}
type Query {
entries (search: String!): [Entry!]!
}
query.gql
query entries ($search: String!) {
entries(search: $search) {
id
}
}
query.ts
export interface entries_entries {
__typename: "Entry";
id: string;
}
export interface entries {
entries: entries_entries[];
}
export interface entriesVariables {
search: string;
}
Using client.query<entries, entriesVariables>
or client.watchQuery<entries, entriesVariables>
the returned type indicates that the field data
has the type data?: entries
, but not that it could also be {}
. This can lead to some unexpected behavior if the user is not aware that data will be {}
in the above mentioned cases.
This could be fixed for example by changing the signature of client.watchQuery
to
watchQuery<T = any, TVariables = OperationVariables>(options: WatchQueryOptions<TVariables>): ObservableQuery<T|{},
TVariables>;
As for client.query
, it could be overloaded in a way that it returns Promise<ApolloQueryResult<T|{}>>
instead of Promise<ApolloQueryResult<T>>
when fetch-policy is set to cache-only
.
An alternative solution would be to leave the types unchanged and return data: undefined
instead of data: {}
.
Versions
System:
OS: Linux 4.4 Ubuntu 20.04 LTS (Focal Fossa)
Binaries:
Node: 14.2.0
Yarn: 1.22.4
npm: 6.14.4
npmPackages:
@apollo/client: ^3.0.0-rc.10 => 3.0.0-rc.10
apollo: ^2.28.3 => 2.28.3
Does this issue persist with the latest release?
During upgrading my own codebase I've noticed that data
is now declared as possibly being undefined
There were already cases where data can be undefined before version 3.0. The graphql spec itself defines that data can be omitted if for example an error occured. To better indicate that, data was set to being optional in version 3.0 I think. This is how ApolloQueryResult currently looks like:
type ApolloQueryResult<T> = {
data?: T;
errors?: ReadonlyArray<GraphQLError>;
loading: boolean;
networkStatus: NetworkStatus;
};
The issue I am describing above is that apollo client 3.0 will return data: {}
in some cases where the cache is involved, which is not reflected in ApolloQueryResult
. I am seeing this behavior in the latest 3.0.2 release.
This should no longer be an issue in @apollo/client@latest
- let us know otherwise, thanks!
I am still getting data: {}
with @apollo/[email protected]
whenever the cache does not contain the query and a fetch-policy like cache-only
is used. Here is a demo project where you can observe this behaviour.
Nowadays I use Partial<>
like this whenever the cache is involed to make sure that I do not forget to handle the case where data does not contain the query:
const {data} = await client.query<Partial<Entries>, EntriesVariables>({
query: entriesQuery,
variables,
fetchPolicy: 'cache-only'
});
I'm not sure if the exact same issue, but I'm running into a similar issue with v3.8.8. I'm using cache.modify to update a list in the root query. The first time through, the existingRefs is an array. The second time through the existingRefs is an object with numeric keys. My code is identical to the example found at https://www.apollographql.com/docs/react/caching/cache-interaction/#example-adding-an-item-to-a-list.
If this isn't the same issue, I'll create another issue with a reproducible repo.
@jantoine1 that seems like another issue, please open a new issue with a code example :)