Build1 distinct publisher2 min readUpdated
The new @ngrx/signals/resource entry point patches two behaviours Angular does not let you configure per resource, and hands back the same resource type. It is also marked experimental.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
Follow any of these and your For You feed starts watching them — no settings page required.
The version of this most teams already have is a `computed()` that holds the last defined value, plus a status check wrapped around every read. It works, and it hands back a Signal, so anything downstream that wanted the resource itself has to be given the original as well. `extendResource` returns the exact resource that went in, with access to more specific types such as `WritableResource` preserved [5], and only `value()` behaves differently [10]. That is the part that justifies the edit: there is no second object to keep in sync with the first.
The four built-ins are a two-by-two [7]. Two moments when `value()` is not what you want, loading and error, and two answers for each: the last resolved value, or a fallback you name [c7d].
Because only `value()` is patched, `error()` and `status()` still report what happened [c10d]. That is worth being deliberate about. With `withValueOnError(undefined)` applied, the read that used to throw now returns a value [6], so any code path that let the throw do the signalling needs an explicit check instead. The NgRx announcement's stated case for `withPreviousValueOnLoading` is paginated and filtered lists that flicker while a reload is in flight [12], and that is the one where the change stays invisible to everything around it.
The scoping reads better than it deploys. `provideResourceExtensions` registers extensions for an injector scope, application, route or component, and composes with what parent injectors registered [8], so a default set at bootstrap can be refined further down. But extensions still arrive through the wrapper: with globals in place, passing the resource alone to `extendResource` is enough [9]. A resource created by a bare `httpResource()` call and never passed through `extendResource` keeps Angular's original behaviour [c9d]. One provider at bootstrap does not change how an existing codebase behaves; it changes what each call site gets once someone has edited that call site. The work is priced per resource, not per application.
Set against that, the entry point is marked experimental [11]. Deleting a hand-written cache in its favour swaps code you control for an API whose signatures can still move, and the failure mode of a moved signature is a compile error rather than a silent behaviour change, which is the cheaper of the two.
The same release does the equivalent tidying for state shapes: a union slice used to collapse into a single flat `Signal`, and now each object-literal member of the union gets its own `DeepSignal` [13]. Both changes take away glue code rather than add surface, which is a more useful thing for a major version to do than it sounds.
Ranked by verification strength, evidence, and original report placement.
In Angular's resource and httpResource APIs, when a resource reloads, value() resets to undefined until the new data arrives.
When an Angular resource enters the error state, reading value() throws.
NgRx v22 adds a @ngrx/signals/resource entry point providing resource extensions: utilities that wrap an existing Resource and patch only the parts of its behaviour that should change.
The extendResource function accepts the resource as its first argument, followed by the extensions to apply.
The resource returned by extendResource is still the exact resource that was passed in, so no access is lost to the APIs of more specific resource types such as WritableResource.
In the documented example, extendResource with withPreviousValueOnLoading() and withValueOnError(undefined) keeps the previously loaded todos while a reload is in flight and returns undefined instead of throwing when the request fails.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
First-party and specific, but uncorroborated
The single source is the authoring team's own release note, which is authoritative for what the library does and is unusually concrete: named APIs, call signatures, compiling code samples, and the exact scope of the patch. What it lacks is any external verification, measurement, or second publisher, and the benefit claim for paginated lists is asserted rather than demonstrated.
Shipped in a major release, no usage data
A real adoption datapoint exists — the feature is shipped in NgRx v22 rather than proposed — but nothing beyond it. There are no downloads, deployments, migration reports or named users in the supplied material, and the experimental marking argues against broad production standardisation so far.
Slightly overstated benefit, honest scope
The release note is mostly proportionate: it names the exact limitation it fixes, scopes the patch to value(), and volunteers the experimental label. It tips mildly positive because the flicker-avoidance framing ('exactly what paginated and filtered lists need') is unmeasured, and because masking errors in value() while error()/status() still fail is left for the reader to work out.
Vendor announcing its own library
The only source is NgRx's own launch post, written to drive upgrades to v22 and usage of a new entry point, and republished on a developer platform without editorial filtering. That is a strong and undisguised promotional incentive; it is partly offset by the voluntary experimental caveat and by the technical specificity, which makes the claims falsifiable by any reader.
High on mechanics, low on impact
Confidence is high that the APIs exist and behave as described, because the vendor is the authoritative source and provides code-level detail. It is low that the change matters at scale: one publisher, no independent testing, no adoption evidence, and an experimental label that could move the surface.
build
Angular's compiler already knows the line number. Nothing ships it to the browser1 distinct publisher
build
Disabling Submit Fixes the Click, Not the Lost Response1 distinct publisher
build
Four field types encrypted, one left readable: the decision that prices per-user envelope encryption1 distinct publisher
build
Three manual interventions in a month, and every guard was working as designed1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 24, 2026