Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(core): resource composition via snapshots - #66328

Merged
thePunderWoman merged 1 commit into
angular:mainfrom
alxhub:resource-snapshots
Jan 12, 2026
Merged

thePunderWoman merged 1 commit into
angular:mainfrom
alxhub:resource-snapshots

Conversation

@alxhub

@alxhub alxhub commented Jan 5, 2026

Copy link
Copy Markdown
Member
  • Define ResourceSnapshot<T> as a type union of possible states for a Resource<T>.
  • Add Resource.snapshot() to convert a Resource to a signal of its snapshot.
  • Add resourceFromSnapshots to convert a reactive snapshot back into a Resource.

By converting resources from/to Signal<ResourceSnapshot>s, full composition of resources is now possible on top of signal composition APIs like computed and linkedSignal.

For example, a common feature request is to have a Resource which retains its value when its reactive source (params) changes. This can now be built as a utility, leveraging linkedSignal's previous value capability:

function withPreviousValue<T>(input: Resource<T>): Resource<T> {
  const derived = linkedSignal({
    source: input.snapshot,
    computation: (snap, previous) => {
      if (snap.status === 'loading' && previous?.value) {
        // When the input resource enters loading state, we keep the value
        // from its previous state, if any.
        return {status: 'loading', value: previous.value.value};
      }

      // Otherwise we simply forward the state of the input resource.
      return snap;
    },
  });

  return resourceFromSnapshots(derived);
}

// In application code:

userId = input.required<number>();
user = withPreviousValue(httpResource(() => `/user/{this.userId()}`));
// if `userId()` switches, `user.value()` will keep the old value until
// the new one is ready!

* Define `ResourceSnapshot<T>` as a type union of possible states for a
`Resource<T>`.
* Add `Resource.snapshot()` to convert a `Resource` to a signal of its
  snapshot.
* Add `resourceFromSnapshots` to convert a reactive snapshot back into a
  `Resource`.

By converting resources from/to `Signal<ResourceSnapshot>`s, full
composition of resources is now possible on top of signal composition APIs
like `computed` and `linkedSignal`.

For example, a common feature request is to have a `Resource` which retains
its value when its reactive source (params) changes. This can now be built
as a utility, leveraging `linkedSignal`'s previous value capability:

```ts
function withPreviousValue<T>(input: Resource<T>): Resource<T> {
  const derived = linkedSignal({
    source: input.snapshot,
    computation: (snap, previous) => {
      if (snap.status === 'loading' && previous?.value) {
        // When the input resource enters loading state, we keep the value
        // from its previous state, if any.
        return {status: 'loading', value: previous.value.value};
      }

      // Otherwise we simply forward the state of the input resource.
      return snap;
    },
  });

  return resourceFromSnapshots(derived);
}

// In application code:

userId = input.required<number>();
user = withPreviousValue(httpResource(() => `/user/{this.userId()}`));
// if `userId()` switches, `user.value()` will keep the old value until
// the new one is ready!
```
@angular-robot angular-robot Bot added detected: feature PR contains a feature commit area: core Issues related to the framework runtime labels Jan 5, 2026
@ngbot ngbot Bot added this to the Backlog milestone Jan 5, 2026
@alxhub
alxhub marked this pull request as ready for review January 7, 2026 17:03
@pullapprove
pullapprove Bot requested review from kirjs and thePunderWoman January 7, 2026 17:04
@alxhub alxhub added the target: minor This PR is targeted for the next minor release label Jan 7, 2026

@JeanMeche JeanMeche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

@thePunderWoman thePunderWoman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

reviewed-for: fw-general, public-api

Comment thread packages/core/src/resource/from_snapshots.ts
Comment thread packages/core/src/resource/api.ts
@JeanMeche

Copy link
Copy Markdown
Member

TESTED=TGP

@JeanMeche JeanMeche added the action: merge The PR is ready for merge by the caretaker label Jan 12, 2026
@thePunderWoman
thePunderWoman merged commit 1ba9b7a into angular:main Jan 12, 2026
26 checks passed
@thePunderWoman

Copy link
Copy Markdown
Contributor

This PR was merged into the repository. The changes were merged into the following branches:

@angular-automatic-lock-bot

Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot Bot locked and limited conversation to collaborators Feb 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants