Skip to content

Commit

Permalink
Merge pull request #11431 from apollographql/pr/fix-resubscribe
Browse files Browse the repository at this point in the history
change re-subscription order
  • Loading branch information
jerelmiller authored Dec 15, 2023
2 parents c388607 + 14d680a commit 8cd67f0
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 17 deletions.
3 changes: 3 additions & 0 deletions src/core/ObservableQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,9 @@ Did you mean to call refetch(variables) instead of refetch({ variables })?`,
this.subscriptions.clear();
this.queryManager.stopQuery(this.queryId);
this.observers.clear();
// this would actually be a good idea to prevent accidental errors,
// but would also be bound to make this class a lot more complicated
// this.queryInfo = undefined;
this.isTornDown = true;
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/QueryInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ export class QueryInfo {
private lastWatch?: Cache.WatchOptions;

private updateWatch(variables = this.variables) {
// this is not *required* to make the tests pass, but would be a good idea?
// this.stopped = false;
const oq = this.observableQuery;
if (oq && oq.options.fetchPolicy === "no-cache") {
return;
Expand Down
32 changes: 17 additions & 15 deletions src/react/cache/QueryReference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,26 @@ export class InternalQueryReference<TData = unknown> {

const originalFetchPolicy = this.watchQueryOptions.fetchPolicy;

const observer = {
next: this.handleNext,
error: this.handleError,
};

if (originalFetchPolicy !== "no-cache") {
observable.resetLastResults();
observable.forceDiff();
observable.silentSetOptions({ fetchPolicy: "cache-first" });
} else {
observable.silentSetOptions({ fetchPolicy: "standby" });
}

this.subscription = observable
.filter(
(result) => !equal(result.data, {}) && !equal(result, this.result)
)
.subscribe(observer);

if (originalFetchPolicy !== "no-cache") {
observable.forceDiff();

const result = this.observable.getCurrentResult();

Expand All @@ -206,20 +222,6 @@ export class InternalQueryReference<TData = unknown> {
}
}

const observer = {
next: this.handleNext,
error: this.handleError,
};

// Avoid triggering reobserve when resubscribing
observable["observers"].add(observer);

this.subscription = observable
.filter(
(result) => !equal(result.data, {}) && !equal(result, this.result)
)
.subscribe(observer);

observable.silentSetOptions({ fetchPolicy: originalFetchPolicy });
}

Expand Down
13 changes: 11 additions & 2 deletions src/react/query-preloader/__tests__/createQueryPreloader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,12 @@ test("useReadQuery auto-resubscribes the query after its disposed", async () =>

let count = 0;
const link = new ApolloLink((operation) => {
let returnedCount = ++count;
return new Observable((observer) => {
setTimeout(() => {
observer.next({ data: { greeting: `Hello ${++count}` } });
observer.next({ data: { greeting: `Hello ${returnedCount}` } });
observer.complete();
}, 10);
}, 100);
});
});

Expand Down Expand Up @@ -384,9 +385,17 @@ test("useReadQuery auto-resubscribes the query after its disposed", async () =>
},
});

// we wait a moment to ensure no network request is triggered
// by the `cache.modify` (even with a slight delay)
await new Promise((resolve) => setTimeout(resolve, 10));
expect(count).toBe(1);

// mount ReadQueryHook
await act(() => user.click(toggleButton));

// this should now trigger a network request
expect(count).toBe(2);

expect(queryRef).not.toBeDisposed();

{
Expand Down

0 comments on commit 8cd67f0

Please sign in to comment.