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;