Skip to content

Patterns

The Guide shows the recommended three-file pattern. A singleton factory service is leaner for simple read-only screens.

A singleton service owns HTTP, cache, and factory methods. It returns CachedResourceRef directly. The consumer provides reactive params and Angular manages the lifecycle. No separate Store is needed.

order.api-cached.ts
@Injectable({ providedIn: 'root' })
export class OrderApiCached {
readonly #http = inject(HttpClient)
readonly #cache = new DataCache()
getAll(params: () => OrderFilters | undefined) {
return cachedResource({
cache: this.#cache,
cacheKey: p => ['order', 'list', p.status],
params,
loader: ({ params }) => this.#http.get<Order[]>('/orders', { params: { ...params } }),
})
}
getById(id: () => string | null) {
return cachedResource({
cache: this.#cache,
cacheKey: p => ['order', 'details', p.id],
params: () => { const v = id(); return v ? { id: v } : undefined },
loader: ({ params }) => this.#http.get<Order>(`/orders/${params.id}`),
})
}
}
order-list.component.ts
readonly #api = inject(OrderApiCached)
readonly filters = signal<OrderFilters>({ status: 'all' })
readonly orders = this.#api.getAll(() => this.filters())

This keeps HTTP, cache, and keys together. Consumers do not wire cache or cacheKey, while the returned CachedResourceRef retains every SWR signal.

API + Store + Component ApiCached + Component
Mutations and optimistic updates Read-only data fetching
Derived state and complex UI logic Simple list or detail views
Multiple coordinated resources Fewer files and less boilerplate

Both patterns use the same library API. cachedResource() behaves identically; this is an organizational choice.