Angular 22

Resource API Enhancements

Angular 22 brings significant improvements to the Resource API: SSR caching via id, special params statuses, streaming resources, and composition via snapshots.

1. SSR Caching with id

Pass an id to resource() to cache its value in TransferState during SSR. The client reuses the cached data instead of re-fetching , zero network requests for the initial load.

Leanne Graham

Sincere@april.biz

Status: resolved

userResource = resource<User, number>({
  id: 'featured-user', // SSR transfer cache key
  params: () => 1,
  loader: async ({ params: userId }) => {
    const res = await fetch(\`/api/users/\${userId}\`);
    return res.json();
  },
  defaultValue: { id: 0, name: 'Loading...' },
});

2. ResourceParamsStatus

Throw ResourceParamsStatus.IDLE or .LOADING from the params function to control the resource state without triggering the loader.

No user selected , resource is idle

Status: idle

selectedUserId = signal<number | null>(null);

userDetail = resource<User, number>({
  params: () => {
    const id = this.selectedUserId();
    if (id === null) {
      throw ResourceParamsStatus.IDLE; // no fetch, stays idle
    }
    return id;
  },
  loader: async ({ params }) => fetch(\`/api/users/\${params}\`).then(r => r.json()),
});

3. Streaming resource

Use stream instead of loader to return a signal that can push synchronous value updates over time , perfect for WebSocket feeds, Server-Sent Events, or polling patterns.

Stream #0: initializing...

Status: resolved

streamResource = resource<string, number>({
  params: () => this.counter(),
  stream: ({ params }) => {
    const value = signal({ value: 'initializing...' });
    // Push updates synchronously
    const interval = setInterval(() => {
      value.set({ value: \`update \${step}\` });
    }, 600);
    return value;
  },
});

4. Composition via Snapshots

Compose multiple resources into one using resourceFromSnapshots(). It merges the .snapshot signals of child resources into a unified Resource. Use ctx.chain() to cascade params between resources.

sunt aut facere repellat provident occaecati excepturi optio reprehenderit

quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto

Author:Leanne Graham(Sincere@april.biz)

Status: resolved

// Resource A
postResource = resource({ params: () => this.postId(), loader: ... });

// Resource B ,  chained off A
authorResource = resource({
  params: (ctx) => {
    const post = ctx.chain(this.postResource); // waits for post
    return post.userId;
  },
  loader: ...
});

// Composed view
composedResource = resourceFromSnapshots(() => {
  const post = this.postResource.snapshot();
  const author = this.authorResource.snapshot();
  // Merge snapshots into one ResourceSnapshot
  ...
});

Summary

  • id option , Cache resource data in TransferState during SSR. The client rehydrates from cache without re-fetching.
  • ResourceParamsStatus , Throw .IDLE or .LOADING from params to control the resource state without triggering the loader.
  • stream , Return a signal from the loader that pushes synchronous updates. Perfect for real-time data sources.
  • resourceFromSnapshots() , Compose multiple resources into one by merging their snapshot signals.
  • ctx.chain() , In the params function, chain off another resource's value. Propagates loading/error states automatically.