Skip to main content

signal.fragment

Read and reactively track a GraphQL fragment in the cache using Signals.

API

Apollo.signal.fragment<TData, TVariables>(
options: SignalFragmentOptions<TData, TVariables>
): SignalFragment<TData, TVariables>

Returns a SignalFragment instance with reactive Signals (result, data, complete, missing).

Options
PropertyTypeDescription
fragmentDocumentNode | TypedDocumentNode<TData, TVariables>A GraphQL fragment document parsed into an AST with the gql
template literal.
fromTFrom | (() => TFrom)An object containing a __typename and primary key fields
(such as id) identifying the entity object from which the fragment will
be retrieved, or a { __ref: "..." } reference, or a string ID
(uncommon).
fragmentName?stringThe name of the fragment defined in the fragment document.

Required if the fragment document includes more than one fragment,
optional otherwise.
optimistic?booleanIf true, watchFragment returns optimistic results.

The default value is true.
injector?InjectorCustom injector to use for this signal.
variables?() => TVariables | undefinedThe operation's variables, as a function or signal re-read whenever its reactive dependencies change.
Signals
SignalTypeDescription
resultSignal<WatchFragmentResult<TData>>The fragment result, containing data, complete, and missing.
dataSignal<WatchFragmentResult<TData>['data']>The data the cache holds for the fragment. Narrow result on complete to reach fully typed data.
completeSignal<boolean>true if all requested fields in the fragment are present in the cache, false otherwise.
missingSignal<MissingTree | undefined>If complete is false, this field describes which fields are missing.
variablesSignal<TVariables | undefined>The variables the fragment is currently reading the cache with.

Watching a fragment

Inject Apollo and call signal.fragment, providing the fragment document and the cache identifier (from).

author-detail/author-detail.component.ts
import { Apollo } from '@apollo-orbit/angular';
import { AuthorFragmentDoc } from '../graphql';

@Component({
selector: 'app-author-detail',
template: `
<h3>Author Details</h3>
@if (authorFragment.data(); as author) {
<p>ID: {{ author.id }}</p>
<p>Name: {{ author.name }}</p>
}
`
})
export class AuthorDetailComponent {
private readonly apollo = inject(Apollo);

public readonly authorId = input.required<string>();

protected readonly authorFragment = this.apollo.signal.fragment({
fragment: AuthorFragmentDoc,
from: () => ({ __typename: 'Author', id: this.authorId() })
});
}
tip

In the example above, __typename can be omitted (e.g. from: { id: '1' })
Orbit extracts the type name from the fragment selected by fragmentName. When the document contains multiple fragments, supply fragmentName to select the one to read. Without it, type-name inference falls back to the first fragment definition.

If you declare a stricter FromOptionValue type, inputs must satisfy it, including __typename when required. See Orbit's fragment-reference support.

SignalFragment automatically reacts to changes in from and variables options if they are provided as signals or functions.

When providing variables, use a function or signal, such as variables: () => ({ locale: this.locale() }). Required GraphQL variables must be supplied, and null variables are not accepted.

Narrowing on complete

result() is a discriminated union: when complete is true, data is the full TData, and when it is false, data holds whatever subset of fields the cache had.

@if (authorFragment.result(); as result) {
@if (result.complete) {
<p>Name: {{ result.data.name }}</p>
}
}
note

The standalone data() signal is the union of both branches, because a signal cannot be narrowed by a different signal's value, so every field reads as possibly missing. Read result() and branch on complete wherever you need the fully-typed shape.