Skip to content

Commit

Permalink
Add QueryOptions and QueryBaseOptions interfaces
Browse files Browse the repository at this point in the history
`ApolloClient.query` is currently configured to accept
`WatchQueryOptions`, which means the docs show people that
passing things like `pollingInterval` into `ApolloClient.query`
is supported (when in reality it's only supported when using
`ApolloClient.watchQuery`). These changes add a new
`QueryOptions` interface, and pull some of the common options
out into a parent `QueryBaseOptions` interface.
`ApolloClient.query` has been updated to use the `QueryOptions`
interface, which should help clear up a bit of confusion.

Fixes #3395.
  • Loading branch information
hwillson committed Jun 11, 2018
1 parent 875bce2 commit eb89b23
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 30 deletions.
18 changes: 10 additions & 8 deletions packages/apollo-client/src/ApolloClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ObservableQuery } from './core/ObservableQuery';
import { Observable } from './util/Observable';

import {
QueryOptions,
WatchQueryOptions,
SubscriptionOptions,
MutationOptions,
Expand All @@ -33,7 +34,7 @@ import { version } from './version';

export interface DefaultOptions {
watchQuery?: ModifiableWatchQueryOptions;
query?: ModifiableWatchQueryOptions;
query?: QueryOptions;
mutate?: MutationBaseOptions;
}

Expand Down Expand Up @@ -221,15 +222,15 @@ export default class ApolloClient<TCacheShape> implements DataProxy {
}

/**
* This resolves a single query according to the options specified and returns a
* {@link Promise} which is either resolved with the resulting data or rejected
* with an error.
* This resolves a single query according to the options specified and
* returns a {@link Promise} which is either resolved with the resulting data
* or rejected with an error.
*
* @param options An object of type {@link WatchQueryOptions} that allows us to describe
* how this query should be treated e.g. whether it is a polling query, whether it should hit the
* @param options An object of type {@link QueryOptions} that allows us to
* describe how this query should be treated e.g. whether it should hit the
* server at all or just resolve from the cache, etc.
*/
public query<T>(options: WatchQueryOptions): Promise<ApolloQueryResult<T>> {
public query<T>(options: QueryOptions): Promise<ApolloQueryResult<T>> {
this.initQueryManager();

if (this.defaultOptions.query) {
Expand All @@ -242,7 +243,8 @@ export default class ApolloClient<TCacheShape> implements DataProxy {
);
}

// XXX Overwriting options is probably not the best way to do this long term...
// XXX Overwriting options is probably not the best way to do this long
// term...
if (this.disableNetworkFetches && options.fetchPolicy === 'network-only') {
options = { ...options, fetchPolicy: 'cache-first' } as WatchQueryOptions;
}
Expand Down
17 changes: 4 additions & 13 deletions packages/apollo-client/src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { MutationStore } from '../data/mutations';
import { QueryStore, QueryStoreValue } from '../data/queries';

import {
QueryOptions,
WatchQueryOptions,
SubscriptionOptions,
MutationOptions,
Expand Down Expand Up @@ -657,10 +658,11 @@ export class QueryManager<TStore> {
});
}

public query<T>(options: WatchQueryOptions): Promise<ApolloQueryResult<T>> {
public query<T>(options: QueryOptions): Promise<ApolloQueryResult<T>> {
if (!options.query) {
throw new Error(
'query option is required. You must specify your GraphQL document in the query option.',
'query option is required. You must specify your GraphQL document ' +
'in the query option.',
);
}

Expand All @@ -672,17 +674,6 @@ export class QueryManager<TStore> {
throw new Error('returnPartialData option only supported on watchQuery.');
}

if ((options as any).pollInterval) {
throw new Error('pollInterval option only supported on watchQuery.');
}

if (typeof options.notifyOnNetworkStatusChange !== 'undefined') {
throw new Error(
'Cannot call "query" with "notifyOnNetworkStatusChange" option. Only "watchQuery" has that option.',
);
}
options.notifyOnNetworkStatusChange = false;

const requestId = this.idCounter;

return new Promise<ApolloQueryResult<T>>((resolve, reject) => {
Expand Down
49 changes: 40 additions & 9 deletions packages/apollo-client/src/core/watchQueryOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,15 @@ export type FetchPolicy =
export type ErrorPolicy = 'none' | 'ignore' | 'all';

/**
* We can change these options to an ObservableQuery
* Common options shared across all query interfaces.
*/
export interface ModifiableWatchQueryOptions<TVariables = OperationVariables> {
export interface QueryBaseOptions<TVariables = OperationVariables> {
/**
* A map going from variable name to variable value, where the variables are used
* within the GraphQL query.
*/
variables?: TVariables;

/**
* The time interval (in milliseconds) on which this query should be
* refetched from the server.
*/
pollInterval?: number;

/**
* Specifies the {@link FetchPolicy} to be used for this query
*/
Expand All @@ -63,6 +57,18 @@ export interface ModifiableWatchQueryOptions<TVariables = OperationVariables> {
* Whether or not to fetch results
*/
fetchResults?: boolean;
}

/**
* We can change these options to an ObservableQuery
*/
export interface ModifiableWatchQueryOptions<TVariables = OperationVariables>
extends QueryBaseOptions<TVariables> {
/**
* The time interval (in milliseconds) on which this query should be
* refetched from the server.
*/
pollInterval?: number;

/**
* Whether or not updates to the network status should trigger next on the observer of this query
Expand All @@ -71,7 +77,7 @@ export interface ModifiableWatchQueryOptions<TVariables = OperationVariables> {
}

/**
* The argument to a query
* Watched query options.
*/
export interface WatchQueryOptions<TVariables = OperationVariables>
extends ModifiableWatchQueryOptions<TVariables> {
Expand All @@ -94,6 +100,31 @@ export interface WatchQueryOptions<TVariables = OperationVariables>
context?: any;
}

/**
* Query options.
*/
export interface QueryOptions<TVariables = OperationVariables>
extends QueryBaseOptions<TVariables> {
/**
* A GraphQL document that consists of a single query to be sent down to the
* server.
*/
// TODO REFACTOR: rename this to document. Didn't do it yet because it's in a
// lot of tests.
query: DocumentNode;

/**
* Arbitrary metadata stored in the store with this query. Designed for debugging,
* developer tools, etc.
*/
metadata?: any;

/**
* Context to be passed to link execution chain
*/
context?: any;
}

export interface FetchMoreQueryOptions<TVariables, K extends keyof TVariables> {
query?: DocumentNode;
variables?: Pick<TVariables, K>;
Expand Down

0 comments on commit eb89b23

Please sign in to comment.