Skip to content

Commit

Permalink
Avoid refetching observerless queries with reFetchObservableQueries (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
joshjg committed Oct 13, 2020
1 parent 28808ce commit 46f5cf5
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/core/ObservableQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,10 @@ once, rather than every time you call fetchMore.`);
},
};

public hasObservers() {
return this.observers.size > 0;
}

private tearDownQuery() {
const { queryManager } = this;

Expand Down
2 changes: 1 addition & 1 deletion src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ export class QueryManager<TStore> {
const observableQueryPromises: Promise<ApolloQueryResult<any>>[] = [];

this.queries.forEach(({ observableQuery }, queryId) => {
if (observableQuery) {
if (observableQuery && observableQuery.hasObservers()) {
const fetchPolicy = observableQuery.options.fetchPolicy;

observableQuery.resetLastResults();
Expand Down
99 changes: 95 additions & 4 deletions src/core/__tests__/QueryManager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3506,9 +3506,18 @@ describe('QueryManager', () => {
}
}
`;

const queryManager = mockQueryManager(reject);
const data = {
author: {
firstName: 'John',
lastName: 'Smith',
},
};
const queryManager = mockQueryManager(reject, {
request: { query },
result: { data }
});
const obs = queryManager.watchQuery<any>({ query });
obs.subscribe({});
obs.refetch = resolve as any;

queryManager.resetStore();
Expand Down Expand Up @@ -3536,6 +3545,7 @@ describe('QueryManager', () => {
let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
Expand Down Expand Up @@ -3570,6 +3580,41 @@ describe('QueryManager', () => {

let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
};

queryManager.resetStore();

setTimeout(() => {
expect(refetchCount).toEqual(0);
resolve();
}, 50);
});

itAsync('should not call refetch on a non-subscribed Observable if the store is reset', (resolve, reject) => {
const query = gql`
query {
author {
firstName
lastName
}
}
`;

const queryManager = createQueryManager({
link: mockSingleLink().setOnError(reject),
});

const options = {
query,
} as WatchQueryOptions;

let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.refetch = () => {
++refetchCount;
Expand Down Expand Up @@ -3906,10 +3951,19 @@ describe('QueryManager', () => {
}
}
`;

const queryManager = mockQueryManager(reject);
const data = {
author: {
firstName: 'John',
lastName: 'Smith',
},
};
const queryManager = mockQueryManager(reject, {
request: { query },
result: { data },
});

const obs = queryManager.watchQuery({ query });
obs.subscribe({});
obs.refetch = resolve as any;

queryManager.reFetchObservableQueries();
Expand Down Expand Up @@ -3937,6 +3991,7 @@ describe('QueryManager', () => {
let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
Expand Down Expand Up @@ -3972,6 +4027,7 @@ describe('QueryManager', () => {
let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
Expand Down Expand Up @@ -4007,6 +4063,7 @@ describe('QueryManager', () => {
let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.subscribe({});
obs.refetch = () => {
++refetchCount;
return null as never;
Expand All @@ -4021,6 +4078,40 @@ describe('QueryManager', () => {
}, 50);
});

itAsync('should not call refetch on a non-subscribed Observable', (resolve, reject) => {
const query = gql`
query {
author {
firstName
lastName
}
}
`;

const queryManager = createQueryManager({
link: mockSingleLink().setOnError(reject),
});

const options = {
query
} as WatchQueryOptions;

let refetchCount = 0;

const obs = queryManager.watchQuery(options);
obs.refetch = () => {
++refetchCount;
return null as never;
};

queryManager.reFetchObservableQueries();

setTimeout(() => {
expect(refetchCount).toEqual(0);
resolve();
}, 50);
});

itAsync('should NOT throw an error on an inflight query() if the observed queries are refetched', (resolve, reject) => {
let queryManager: QueryManager<NormalizedCacheObject>;
const query = gql`
Expand Down

0 comments on commit 46f5cf5

Please sign in to comment.