diff --git a/CHANGELOG.md b/CHANGELOG.md
index 348374151e0..22703722a64 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -206,6 +206,9 @@
- Migrated React Apollo HOC and Components functionality into Apollo Client, making it accessible from `@apollo/client/react/components` and `@apollo/client/react/hoc` entry points.
[@hwillson](https://github.com/hwillson) in [#6558](https://github.com/apollographql/apollo-client/pull/6558)
+- Support passing a `context` object through the link execution chain when using subscriptions.
+ [@sgtpepper43](https://github.com/sgtpepper43) in [#4925](https://github.com/apollographql/apollo-client/pull/4925)
+
### Bug Fixes
- `useMutation` adjustments to help avoid an infinite loop / too many renders issue, caused by unintentionally modifying the `useState` based mutation result directly.
diff --git a/src/__tests__/graphqlSubscriptions.ts b/src/__tests__/graphqlSubscriptions.ts
index 1ed82838749..82164783387 100644
--- a/src/__tests__/graphqlSubscriptions.ts
+++ b/src/__tests__/graphqlSubscriptions.ts
@@ -29,6 +29,9 @@ describe('GraphQL Subscriptions', () => {
variables: {
name: 'Changping Chen',
},
+ context: {
+ someVar: 'Some value'
+ }
};
defaultOptions = {
@@ -242,4 +245,23 @@ describe('GraphQL Subscriptions', () => {
setTimeout(() => link.simulateComplete(), 100);
});
});
+
+ it('should pass a context object through the link execution chain', done => {
+ const link = mockObservableLink();
+ const client = new ApolloClient({
+ cache: new InMemoryCache(),
+ link,
+ });
+
+ client.subscribe(options).subscribe({
+ next() {
+ expect(link.operation.getContext().someVar).toEqual(
+ options.context.someVar
+ );
+ done();
+ },
+ });
+
+ link.simulateResult(results[0]);
+ });
});
diff --git a/src/core/ObservableQuery.ts b/src/core/ObservableQuery.ts
index a767f2875f8..9918ac66234 100644
--- a/src/core/ObservableQuery.ts
+++ b/src/core/ObservableQuery.ts
@@ -372,6 +372,7 @@ once, rather than every time you call fetchMore.`);
.startGraphQLSubscription({
query: options.document,
variables: options.variables,
+ context: options.context,
})
.subscribe({
next: (subscriptionData: { data: TSubscriptionData }) => {
diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts
index 21cbb5dd739..6eda47de53d 100644
--- a/src/core/QueryManager.ts
+++ b/src/core/QueryManager.ts
@@ -597,6 +597,7 @@ export class QueryManager {
query,
fetchPolicy,
variables,
+ context = {},
}: SubscriptionOptions): Observable> {
query = this.transform(query).document;
variables = this.getVariables(query, variables);
@@ -604,7 +605,7 @@ export class QueryManager {
const makeObservable = (variables: OperationVariables) =>
this.getObservableFromLink(
query,
- {},
+ context,
variables,
false,
).map(result => {
@@ -636,6 +637,7 @@ export class QueryManager {
const observablePromise = this.localState.addExportedVariables(
query,
variables,
+ context,
).then(makeObservable);
return new Observable>(observer => {
diff --git a/src/core/watchQueryOptions.ts b/src/core/watchQueryOptions.ts
index 1da35b5a497..46d7acda81c 100644
--- a/src/core/watchQueryOptions.ts
+++ b/src/core/watchQueryOptions.ts
@@ -140,6 +140,7 @@ export type SubscribeToMoreOptions<
variables?: TSubscriptionVariables;
updateQuery?: UpdateQueryFn;
onError?: (error: Error) => void;
+ context?: Record;
};
export interface SubscriptionOptions {
@@ -159,6 +160,11 @@ export interface SubscriptionOptions {
* Specifies the {@link FetchPolicy} to be used for this subscription.
*/
fetchPolicy?: FetchPolicy;
+
+ /**
+ * Context object to be passed through the link execution chain.
+ */
+ context?: Record;
}
export type RefetchQueryDescription = Array;
diff --git a/src/utilities/testing/mocking/mockSubscriptionLink.ts b/src/utilities/testing/mocking/mockSubscriptionLink.ts
index 635a2b5e8cc..78956933501 100644
--- a/src/utilities/testing/mocking/mockSubscriptionLink.ts
+++ b/src/utilities/testing/mocking/mockSubscriptionLink.ts
@@ -15,6 +15,7 @@ export interface MockedSubscriptionResult {
export class MockSubscriptionLink extends ApolloLink {
public unsubscribers: any[] = [];
public setups: any[] = [];
+ public operation: Operation;
private observer: any;
@@ -22,7 +23,8 @@ export class MockSubscriptionLink extends ApolloLink {
super();
}
- public request(_req: any) {
+ public request(operation: Operation) {
+ this.operation = operation;
return new Observable(observer => {
this.setups.forEach(x => x());
this.observer = observer;