signal.subscription
Subscribe to GraphQL subscriptions and receive real-time updates via reactive Signals.
API
Apollo.signal.subscription<TData, TVariables>(
options: SignalSubscriptionOptions<TVariables, TData>
): SignalSubscription<TData, TVariables>
Returns a SignalSubscription<TData, TVariables>
instance. This object provides reactive Signals (result
, data
, loading
, error
, active
) reflecting the subscription's state. It also includes methods execute
(for lazy subscriptions) and terminate
.
Options
Property | Type | Description |
---|---|---|
subscription | DocumentNode | TypedDocumentNode<TData, TVariables> | A GraphQL document, often created with gql from the graphql-tag package, that contains a single subscription inside of it. |
fetchPolicy? | FetchPolicy | How you want your component to interact with the Apollo cache. For details, see Setting a fetch policy. |
errorPolicy? | ErrorPolicy | Specifies the ErrorPolicy to be used for this operation |
context? | DefaultContext | Shared context between your component and your network interface (Apollo Link). |
extensions? | Record<string, any> | Shared context between your component and your network interface (Apollo Link). |
lazy? | boolean | Whether to execute subscription immediately or lazily via execute method. |
onData? | (data: TData) => void | Callback for when new data is received |
onComplete? | () => void | Callback for when the subscription is completed |
onError? | (error: ErrorLike) => void | Callback for when an error occurs |
injector? | Injector | Custom injector to use for this subscription. |
variables? | () => TVariables | undefined | | A function or signal returning an object containing all of the GraphQL variables your operation requires to execute. Each key in the object corresponds to a variable name, and that key's value corresponds to the variable value.* When null is returned, the subscription will be terminated until a non-null value is returned again. |
Signals
Signal | Type | Description |
---|---|---|
result | Signal<SignalSubscriptionResult<TData>> | The subscription result, containing data , loading , and error . |
loading | Signal<boolean> | If true , the subscription is currently loading the initial result. |
data | Signal<TData | undefined> | The data returned by the subscription, or undefined if loading, errored, or no data received yet. |
error | Signal<ErrorLike | undefined> | An error object if the subscription failed, undefined otherwise. |
active | Signal<boolean> | Whether the subscription is currently active, connected to the server and receiving real-time updates. |
enabled | Signal<boolean> | Whether the subscription is currently enabled. This property starts as true for non-lazy subscriptions and false for lazy subscriptions.Calling execute() sets it to true , while calling terminate() sets it to false .When true :- The subscription automatically starts when variables change from null to a non-null value- Variable changes trigger re-subscription with the new variables When false :- Variable changes are ignored and do not trigger re-subscription - The subscription must be manually started via execute() Note: This is different from active , which indicates whether the subscription is currently connected to the server and receiving real-time updates. |
Methods
Method | Description |
---|---|
execute(execOptions: SignalSubscriptionExecOptions<TVariables>) | Execute subscription. |
terminate() | Terminate subscription. |
Executing a subscription
To execute a subscription within an Angular component using Signals, inject Apollo
and call signal.subscription
with a GraphQL subscription document. The returned SignalSubscription
object's signals can be used directly in your component's template or logic to reactively handle real-time updates.
Let's look at an example using the same subscription from the subscribe guide:
import { Apollo } from '@apollo-orbit/angular';
import { NEW_AUTHOR_SUBSCRIPTION } from '../graphql/types';
@Component({
selector: 'app-authors',
template: `
@if (newAuthorSubscription.data(); as author) {
<div class="alert-info">New author was added: {{ author.newAuthor.name }}</div>
}
@if (newAuthorSubscription.error(); as error) {
<div class="alert-error">Subscription error: {{ error.message }}</div>
}
`
})
export class AuthorsComponent {
private readonly apollo = inject(Apollo);
protected readonly newAuthorSubscription = this.apollo.signal.subscription({
subscription: NEW_AUTHOR_SUBSCRIPTION
});
}
Variables
A variables function or signal may be passed to signal.subscription
options. If the function depends on reactive variables, SignalSubscription
will automatically update and restart the subscription when these reactive variables change.
import { Apollo } from '@apollo-orbit/angular';
import { NEW_BOOK_SUBSCRIPTION } from '../graphql/types';
@Component({
selector: 'app-books',
template: `
<h3>New Books</h3>
@if (newBookSubscription.data(); as data) {
<div class="alert-info">New book added: {{ data.newBook.name }}</div>
}
`
})
export class BooksComponent {
private readonly apollo = inject(Apollo);
// Component input signal
public readonly authorId = input<string>();
protected readonly newBookSubscription = this.apollo.signal.subscription({
subscription: NEW_BOOK_SUBSCRIPTION,
variables: () => ({ authorId: this.authorId() })
});
}
Variables = null
When the variables function returns null
, SignalSubscription
will automatically terminate the subscription:
import { Apollo } from '@apollo-orbit/angular';
import { BOOK_UPDATE_SUBSCRIPTION } from '../graphql/types';
@Component({
selector: 'app-book',
templateUrl: './book.component.html'
})
export class BookComponent {
private readonly apollo = inject(Apollo);
// Component input that might be null initially
public readonly bookId = input<string | null>();
protected readonly bookUpdateSubscription = this.apollo.signal.subscription({
subscription: BOOK_UPDATE_SUBSCRIPTION,
variables: () => {
const id = this.bookId();
return id ? { id } : null; // Return null if bookId is not available
}
});
}
Behavior when variables return null
:
- If the subscription hasn't started yet, it won't start until variables become non-null
- If the subscription is already active, it will terminate (disconnect from the server and stop receiving updates)
- When variables change from
null
to a non-null value, if the subscription isenabled
then it will automatically execute
This pattern is useful for:
- Waiting for required input parameters before starting a subscription
- Conditionally subscribing to updates based on user selections
- Preventing unnecessary subscriptions when dependencies are not ready
Lazy Subscriptions
In some cases, you may want to delay the execution of a subscription until a specific event occurs. This can be achieved by using the lazy
option:
import { Apollo } from '@apollo-orbit/angular';
import { NEW_AUTHOR_SUBSCRIPTION } from '../graphql/types';
@Component({
selector: 'app-authors',
template: `
<button (click)="toggleSubscription()">
{{ newAuthorSubscription.active() ? 'Stop' : 'Start' }} subscription
</button>
@if (newAuthorSubscription.data(); as data) {
<div class="alert-info">New author: {{ data.newAuthor.name }}</div>
}
`
})
export class AuthorsComponent {
private readonly apollo = inject(Apollo);
protected readonly newAuthorSubscription = this.apollo.signal.subscription({
subscription: NEW_AUTHOR_SUBSCRIPTION,
lazy: true, // Delay execution until explicitly called
onData: (data) => {
// Optional callback when new data arrives
console.log('New author:', data.newAuthor.name);
},
onError: (error) => {
// Optional callback for errors
console.error('Subscription error:', error);
},
onComplete: () => {
// Optional callback when subscription completes
console.log('Author subscription completed');
}
});
protected toggleSubscription(): void {
if (this.newAuthorSubscription.active()) {
this.newAuthorSubscription.terminate();
} else {
this.newAuthorSubscription.execute();
}
}
}
Setting lazy: true
makes the subscription variables optional (even if required by the subscription), allowing you to pass them only when executing via the execute
method.
Callbacks
signal.subscription
supports optional callbacks for handling subscription events:
onData
: Called when new data is receivedonError
: Called when an error occursonComplete
: Called when the subscription completes
These callbacks are useful for side effects like logging, analytics, or triggering other actions.
Component Lifecycle
Similar to SignalQuery
, SignalSubscription
uses an effect
internally to manage the subscription lifecycle. The subscription is automatically cleaned up when the component is destroyed, preventing memory leaks.
For non-lazy subscriptions, the subscription starts immediately when the component is created. For lazy subscriptions, you control when to start and stop the subscription using the execute()
and terminate()
methods.