diff --git a/CHANGELOG.md b/CHANGELOG.md
index ecc2ad0fdba..1d625890a2e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -142,6 +142,9 @@
- Refined `useLazyQuery` types to help prevent runtime errors.
[@benmosher](https://github.com/benmosher) in [#5935](https://github.com/apollographql/apollo-client/pull/5935)
+- Make sure `@client @export` variables used in watched queries are updated each time the query receives new data that changes the value of the `@export` variable.
+ [@hwillson](https://github.com/hwillson) in [#5986](https://github.com/apollographql/apollo-client/pull/5986)
+
## Apollo Client 2.6.8
### Apollo Client (2.6.8)
diff --git a/src/__tests__/local-state/export.ts b/src/__tests__/local-state/export.ts
index a771e8d424d..0fb7262c44d 100644
--- a/src/__tests__/local-state/export.ts
+++ b/src/__tests__/local-state/export.ts
@@ -754,8 +754,7 @@ describe('@client @export tests', () => {
});
done();
}
-
- resultCount +=1;
+ resultCount += 1;
}
});
}
@@ -904,4 +903,65 @@ describe('@client @export tests', () => {
});
}
);
+
+ it(
+ "should update @client @export variables on each broadcast if they've " +
+ "changed",
+ done => {
+ const cache = new InMemoryCache();
+
+ const widgetCountQuery = gql`{ widgetCount @client }`;
+ cache.writeQuery({
+ query: widgetCountQuery,
+ data: {
+ widgetCount: 100
+ }
+ });
+
+ const client = new ApolloClient({
+ cache,
+ resolvers: {
+ Query: {
+ doubleWidgets(_, { widgetCount }) {
+ return widgetCount ? widgetCount * 2 : 0;
+ }
+ }
+ }
+ });
+
+ const doubleWidgetsQuery = gql`
+ query DoubleWidgets($widgetCount: Int!) {
+ widgetCount @client @export(as: "widgetCount")
+ doubleWidgets(widgetCount: $widgetCount) @client
+ }
+ `;
+
+ let count = 0;
+ const obs = client.watchQuery({ query: doubleWidgetsQuery });
+ obs.subscribe({
+ next({ data }) {
+ switch (count) {
+ case 0:
+ expect(data.widgetCount).toEqual(100);
+ expect(data.doubleWidgets).toEqual(200);
+
+ client.writeQuery({
+ query: widgetCountQuery,
+ data: {
+ widgetCount: 500
+ }
+ });
+ break;
+ case 1:
+ expect(data.widgetCount).toEqual(500);
+ expect(data.doubleWidgets).toEqual(1000);
+ done();
+ break;
+ default:
+ }
+ count += 1;
+ },
+ });
+ }
+ );
});
diff --git a/src/core/ObservableQuery.ts b/src/core/ObservableQuery.ts
index 66c2e7d66b7..30c805e4f00 100644
--- a/src/core/ObservableQuery.ts
+++ b/src/core/ObservableQuery.ts
@@ -590,10 +590,7 @@ export class ObservableQuery<
iterateObserversSafely(this.observers, 'error', this.lastError = error);
};
- const {
- hasClientExports,
- serverQuery
- } = queryManager.transform(this.options.query);
+ const { hasClientExports } = queryManager.transform(this.options.query);
queryManager.observeQuery(queryId, this.options, {
next: (result: ApolloQueryResult) => {
@@ -605,9 +602,8 @@ export class ObservableQuery<
// Before calling `next` on each observer, we need to first see if
// the query is using `@client @export` directives, and update
// any variables that might have changed. If `@export` variables have
- // changed, and the query is requesting both local and remote
- // data, `setVariables` is used as a network refetch might be
- // needed to pull in new data, using the updated `@export` variables.
+ // changed, `setVariables` is used to query the cache first, followed
+ // by the network if needed.
if (hasClientExports) {
queryManager.getLocalState().addExportedVariables(
query,
@@ -618,11 +614,10 @@ export class ObservableQuery<
!result.loading &&
previousResult &&
fetchPolicy !== 'cache-only' &&
- serverQuery &&
!equal(previousVariables, variables)
) {
this.setVariables(variables).then(updatedResult => {
- iterateObserversSafely(this.observers, 'next', updatedResult)
+ iterateObserversSafely(this.observers, 'next', updatedResult);
});
} else {
this.variables = this.options.variables = variables;