From 12821cfd93f1d1d55449b1380d39e0e7cd8b1c69 Mon Sep 17 00:00:00 2001 From: Leonardo Garcia Crespo Date: Thu, 25 Jan 2018 16:08:02 -0300 Subject: [PATCH] Improve types in Query component. Make data be undefined in initial load. (#1581) --- src/Query.tsx | 30 +++++++++++-------- test/client/Query.test.tsx | 2 +- test/client/__snapshots__/Query.test.tsx.snap | 2 +- test/server/getDataFromTree.test.tsx | 10 +++---- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/Query.tsx b/src/Query.tsx index 639deeaf6b..4b135f5281 100644 --- a/src/Query.tsx +++ b/src/Query.tsx @@ -19,7 +19,9 @@ const shallowEqual = require('fbjs/lib/shallowEqual'); const invariant = require('invariant'); const pick = require('lodash/pick'); -function observableQueryFields(observable) { +type ObservableQueryFields = Pick, 'refetch' | 'fetchMore' | 'updateQuery' | 'startPolling' | 'stopPolling'>; + +function observableQueryFields(observable: ObservableQuery): ObservableQueryFields { const fields = pick( observable, 'refetch', @@ -38,16 +40,20 @@ function observableQueryFields(observable) { return fields; } -export interface QueryResult { +function isDataFilled(data: {} | TData): data is TData { + return Object.keys(data).length > 0; +} + +export interface QueryResult { client: ApolloClient; - data: TData; + data?: TData; error?: ApolloError; fetchMore: ( fetchMoreOptions: FetchMoreQueryOptions & FetchMoreOptions, ) => Promise>; loading: boolean; networkStatus: number; - refetch: (variables?: OperationVariables) => Promise>; + refetch: (variables?: TVariables) => Promise>; startPolling: (pollInterval: number) => void; stopPolling: () => void; updateQuery: ( @@ -55,13 +61,13 @@ export interface QueryResult { ) => void; } -export interface QueryProps { - children: (result: QueryResult) => React.ReactNode; +export interface QueryProps { + children: (result: QueryResult) => React.ReactNode; fetchPolicy?: FetchPolicy; notifyOnNetworkStatusChange?: boolean; pollInterval?: number; query: DocumentNode; - variables?: OperationVariables; + variables?: TVariables; ssr?: boolean; } @@ -69,8 +75,8 @@ export interface QueryState { result: ApolloCurrentResult; } -class Query extends React.Component< - QueryProps, +class Query extends React.Component< + QueryProps, QueryState > { static contextTypes = { @@ -82,7 +88,7 @@ class Query extends React.Component< private queryObservable: ObservableQuery; private querySubscription: ZenObservable.Subscription; - constructor(props: QueryProps, context: any) { + constructor(props: QueryProps, context: any) { super(props, context); invariant( @@ -217,12 +223,12 @@ class Query extends React.Component< this.setState({ result: this.queryObservable.currentResult() }); }; - private getQueryResult = (): QueryResult => { + private getQueryResult = (): QueryResult => { const { result } = this.state; const { loading, error, networkStatus, data } = result; return { client: this.client, - data, + data: isDataFilled(data) ? data : undefined, loading, error, networkStatus, diff --git a/test/client/Query.test.tsx b/test/client/Query.test.tsx index 5821e76c6b..3a50781310 100644 --- a/test/client/Query.test.tsx +++ b/test/client/Query.test.tsx @@ -535,7 +535,7 @@ describe('Query component', () => { {result => { catchAsyncError(done, () => { expect(result.loading).toBeFalsy(); - expect(result.data).toEqual({}); + expect(result.data).toBeUndefined(); expect(result.networkStatus).toBe(7); done(); }); diff --git a/test/client/__snapshots__/Query.test.tsx.snap b/test/client/__snapshots__/Query.test.tsx.snap index c19176c824..f9c6b600da 100644 --- a/test/client/__snapshots__/Query.test.tsx.snap +++ b/test/client/__snapshots__/Query.test.tsx.snap @@ -27,7 +27,7 @@ Object { exports[`Query component calls the children prop: result in render prop while loading 1`] = ` Object { - "data": Object {}, + "data": undefined, "error": undefined, "fetchMore": [Function], "loading": true, diff --git a/test/server/getDataFromTree.test.tsx b/test/server/getDataFromTree.test.tsx index 7b298a41cc..d0790666d9 100644 --- a/test/server/getDataFromTree.test.tsx +++ b/test/server/getDataFromTree.test.tsx @@ -939,11 +939,11 @@ describe('SSR', () => { } } `; - const data = { currentUser: { firstName: 'James' } }; + const resultData = { currentUser: { firstName: 'James' } }; const variables = { id: 1 }; const link = mockSingleLink({ request: { query, variables }, - result: { data }, + result: { data: resultData }, delay: 50, }); @@ -959,12 +959,12 @@ describe('SSR', () => { }; } - class CurrentUserQuery extends Query {} + class CurrentUserQuery extends Query {} const Element = (props: { id: number }) => ( - {({ data: { currentUser }, loading }) => ( -
{loading ? 'loading' : currentUser.firstName}
+ {({ data, loading }) => ( +
{loading || !data ? 'loading' : data.currentUser.firstName}
)}
);