Skip to content

Commit

Permalink
Preserve networkStatus for incomplete cache-and-network queries.
Browse files Browse the repository at this point in the history
Blindly setting networkStatus to NetworkStatus.loading after the client
part of a cache-and-network query was destroying useful information about
the status of the request. Instead, we should use NetworkStatus.ready only
when the request is complete, and leave networkStatus untouched otherwise.

Fixes #3660, #4693, and apollographql/react-apollo#1217.
  • Loading branch information
benjamn committed Apr 30, 2019
1 parent a87d28b commit ab7a908
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 7 deletions.
109 changes: 109 additions & 0 deletions packages/apollo-client/src/core/__tests__/fetchPolicies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import subscribeAndCount from '../../util/subscribeAndCount';
import { withWarning } from '../../util/wrap';

import { mockSingleLink } from '../../__mocks__/mockLinks';
import { NetworkStatus } from '../networkStatus';

const query = gql`
query {
Expand Down Expand Up @@ -345,3 +346,111 @@ describe('no-cache', () => {
});
});
});

describe('cache-and-network', function() {
it('gives appropriate networkStatus for refetched queries', done => {
const client = new ApolloClient({
link: ApolloLink.empty(),
cache: new InMemoryCache(),
resolvers: {
Query: {
hero(_data, args) {
return {
__typename: 'Hero',
...args,
name: 'Luke Skywalker',
};
},
},
},
});

const observable = client.watchQuery({
query: gql`
query FetchLuke($id: String) {
hero(id: $id) @client {
id
name
}
}
`,
fetchPolicy: 'cache-and-network',
variables: { id: '1' },
notifyOnNetworkStatusChange: true,
});

function dataWithId(id: number | string) {
return {
hero: {
__typename: 'Hero',
id: String(id),
name: 'Luke Skywalker',
},
};
}

subscribeAndCount(done, observable, (count, result) => {
if (count === 1) {
expect(result).toEqual({
data: void 0,
loading: true,
networkStatus: NetworkStatus.loading,
stale: true,
});
} else if (count === 2) {
expect(result).toEqual({
data: dataWithId(1),
loading: false,
networkStatus: NetworkStatus.ready,
stale: false,
});
return observable.setVariables({ id: '2' });
} else if (count === 3) {
expect(result).toEqual({
data: dataWithId(1),
loading: true,
networkStatus: NetworkStatus.setVariables,
stale: false,
});
} else if (count === 4) {
expect(result).toEqual({
data: dataWithId(2),
loading: false,
networkStatus: NetworkStatus.ready,
stale: false,
});
return observable.refetch();
} else if (count === 5) {
expect(result).toEqual({
data: dataWithId(2),
loading: true,
networkStatus: NetworkStatus.refetch,
stale: false,
});
} else if (count === 6) {
expect(result).toEqual({
data: dataWithId(2),
loading: false,
networkStatus: NetworkStatus.ready,
stale: false,
});
return observable.refetch({ id: '3' });
} else if (count === 7) {
expect(result).toEqual({
data: dataWithId(2),
loading: true,
networkStatus: NetworkStatus.setVariables,
stale: false,
});
} else if (count === 8) {
expect(result).toEqual({
data: dataWithId(3),
loading: false,
networkStatus: NetworkStatus.ready,
stale: false,
});
done();
}
});
});
});
15 changes: 8 additions & 7 deletions packages/apollo-client/src/data/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,14 @@ export class QueryStore {
}

public markQueryResultClient(queryId: string, complete: boolean) {
if (!this.store || !this.store[queryId]) return;

this.store[queryId].networkError = null;
this.store[queryId].previousVariables = null;
this.store[queryId].networkStatus = complete
? NetworkStatus.ready
: NetworkStatus.loading;
const storeValue = this.store && this.store[queryId];
if (storeValue) {
this.store[queryId].networkError = null;
this.store[queryId].previousVariables = null;
if (complete) {
this.store[queryId].networkStatus = NetworkStatus.ready;
}
}
}

public stopQuery(queryId: string) {
Expand Down

0 comments on commit ab7a908

Please sign in to comment.