Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Angular’s native Resource APIs for most signal-based reads. Choose httpResource when the data comes from HTTP and should use Angular’s HttpClient stack; choose rxResource when the loader naturally returns an RxJS Observable. Add NgRx Resource Extensions when the user experience must keep the last value visible during refreshes or errors, or when those value policies need injector-scoped defaults. Keep writes such as POST and PUT in HttpClient or another command-oriented API rather than treating them as resources.
The practical distinction is value behavior, not transport. Angular supplies the resource lifecycle and integrations; NgRx can wrap that resource and change what consumers see while loading or failing. The trade-off is API maturity: Angular’s Resource APIs are documented as stable in Angular v22, while NgRx Resource Extensions are experimental.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
What is Angular Resource?
Angular defines a Resource as an asynchronous dependency, such as an API result, that is managed and delivered through signals. A resource gives a component or service a consistent way to read the current value and observe its lifecycle instead of manually coordinating a signal, a loading flag, and an error signal.
The core resource exposes value, status, error, isLoading, snapshot, and hasValue. Those properties let a view distinguish a successful value from an in-progress request or a failure. The generic resource() function connects a reactive request to a loader and is intended for read operations.
#1 Best Overall
A resource is reactive: when the request inputs change, Angular can start work for the new request. An in-progress load can be cancelled when the resource is destroyed or when a new request becomes available. That cancellation behavior matters for type-ahead searches, filters, pagination, and route parameters because obsolete responses should not replace the result for the newest request.
How do resource, httpResource, and rxResource differ?
They share the Resource model but target different loaders. Pick the creation API that matches where your asynchronous value comes from.
resource() for a general reactive loader
Use resource() when you need to map a reactive request to your own asynchronous loader. It is the lowest-level choice in this comparison: you define how the value is obtained, while Angular manages its signal-based lifecycle, status, cancellation, and error representation.
Because Angular documents resource() as a read API, it is a poor fit for commands whose purpose is to change server state. A save, delete, or update should be an explicit operation with a success or failure result, not a read resource that happens to issue a mutation.
httpResource() for HTTP reads
httpResource() is a reactive wrapper around HttpClient. It exposes the request status and response as signals, reacts to changes in its request inputs, eagerly initiates requests, and cancels a pending request before issuing a new one.
The important advantage is that it remains inside the normal Angular HTTP pipeline. Interceptors, response parsing, progress handling, and HTTP testing utilities continue to apply. That makes it the default choice for ordinary API reads in an Angular application that already relies on HttpClient conventions.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteRank #2
Angular specifically advises against using httpResource() for mutations such as POST and PUT. Use the underlying HttpClient methods or a command-oriented service for those operations so that writes have an explicit trigger and result.
rxResource() for Observable-based loaders
rxResource() is the Observable-oriented variant. Its loader maps a request to an RxJS Observable that produces the resource value. It is useful when the existing data source, operator chain, or cancellation behavior is already expressed in RxJS and converting that pipeline to a promise or another loader would add friction.
The Angular API reference marks rxResource() stable since Angular v22. In other words, choosing it does not require adopting NgRx merely because the application uses Observables.
| API | Use it when | What Angular manages |
|---|---|---|
resource() |
Your loader is custom and reactive. | Signal delivery, status, errors, loading state, snapshots, and cancellation. |
httpResource() |
The value comes from an HTTP read through Angular. | The Resource lifecycle plus HttpClient interceptors, parsing, progress, and testing support. |
rxResource() |
The loader naturally returns an RxJS Observable. | The Resource lifecycle around the Observable-producing loader. |
What do NgRx Resource Extensions add?
NgRx Resource Extensions do not replace Angular’s resource creation APIs or transport integrations. The @ngrx/signals/resource entry point provides extendResource, which wraps an existing Resource and changes its value behavior while preserving the original resource type.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
That preservation is significant. A wrapped resource still exposes the APIs of the more specific resource that was passed in, including specialized types such as WritableResource. Wrapping an HTTP resource therefore does not turn it into a generic object or remove its HTTP-related capabilities.
The four built-in extensions
| Extension | Behavior | Useful for |
|---|---|---|
withPreviousValueOnLoading() |
Keeps the last resolved value available while a reload is in progress. | Filtered or paginated lists where replacing content with a blank state causes flicker. |
withValueOnLoading(value) |
Provides a chosen fallback value during loading. | Views that need a known shape, such as an empty collection or a skeleton model. |
withPreviousValueOnError() |
Returns the last successful value after a later request fails. | Stale-but-readable screens where preserving context is better than showing no data. |
withValueOnError(value) |
Returns a chosen fallback instead of throwing from value() in an error state. |
Safe defaults for templates or downstream computations that cannot consume an exception. |
Angular’s default semantics create two common surprises. During a reload, the current value can become unavailable. In an error state, reading value() can throw; consumers should use hasValue() when they need to guard that read. NgRx extensions let a team choose a different policy instead of repeating those guards and transitions in every component.
Rank #3
How do loading and error values differ between the two approaches?
Angular gives you the lifecycle signals and leaves the value policy largely to the consumer. NgRx adds explicit policies for what a consumer should see while that lifecycle is changing.
| Situation | Angular Resource behavior | With an NgRx extension |
|---|---|---|
| A request starts again | The previous value may become unavailable while the new load is pending. | Keep the previous value or supply a configured loading fallback. |
| A request fails | Reading value() in the error state can throw; check hasValue() before reading. |
Keep the last successful value or return a configured error fallback. |
| The request is HTTP | httpResource() uses the normal HttpClient stack. |
The wrapped resource retains that HTTP integration. |
| The request is Observable-based | rxResource() maps the request to an Observable. |
The value extensions are independent of that transport choice. |
These are UX and state-semantics decisions, not performance switches. Keeping stale data visible can make a table feel stable while a filter reloads, but it also means the screen may display data that no longer matches the newest request. If that distinction matters, pair the retained value with the resource’s loading or status signal and label the view appropriately.
Should you use NgRx Resource Extensions or Angular Resource?
Start with Angular and add NgRx only when a specific value policy or injector-scoped convention solves a real problem.
Choose Angular’s native APIs when
- The application needs straightforward signal-based reads.
- An HTTP read should pass through Angular interceptors and HTTP testing utilities.
- The loader already returns an RxJS Observable and
rxResource()expresses it directly. - The team prefers stable Angular APIs and can handle loading and error states explicitly.
- Different screens do not need a shared stale-value or fallback policy.
Choose NgRx Resource Extensions when
- A reload should keep the last successful value visible instead of blanking the view.
- An error should preserve useful stale data or return a defined fallback rather than make
value()throw. - Several components need the same loading and error semantics.
- Those semantics should be registered at application, route, or component injector scope.
- The project already uses NgRx Signals and accepts the upgrade risk of an experimental API.
Do not choose either resource API solely for mutations
Resources are read-oriented. For POST, PUT, and similar commands, call HttpClient or another command API from an explicit action, service method, or event handler. Then update or invalidate the read-side state according to the application’s needs. An extension changes how a Resource presents values; it does not turn a read abstraction into a safer mutation abstraction.
How do you keep the previous value while an Angular resource reloads?
Create the specialized Angular resource first, then wrap it with extendResource and the loading or error policy you need. The following is an illustrative TypeScript shape; use the import paths and request options documented for the Angular and NgRx versions installed in your project.
const orders = extendResource(
httpResource(() => buildOrdersRequest(page(), filter())),
withPreviousValueOnLoading(),
withPreviousValueOnError()
);
- Make the request inputs reactive, such as a page signal, filter signal, or route parameter.
- Create the read with
httpResource()so the request usesHttpClient. Useresource()orrxResource()instead when the loader is not an HTTP request or is naturally Observable-based. - Pass the resulting Resource to
extendResource. - Add
withPreviousValueOnLoading()if a refresh should retain the last resolved value. - Add
withPreviousValueOnError()if a failed refresh should continue showing that last successful value. - Render the retained value together with
isLoadingorstatus, so users can tell that a newer result is being fetched or that the displayed data is stale after an error.
If retaining old data is not appropriate, replace the previous-value extensions with withValueOnLoading(fallback) and withValueOnError(fallback). A fallback should match the type and shape expected by the view; otherwise the extension merely moves a type or rendering problem to another part of the component.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRank #4
How do injector-scoped resource policies work?
provideResourceExtensions() can register extension behavior at application, route, or component injector scope. This lets a broad default be established once while a child scope refines it for a feature or screen.
For example, an application can use a consistent fallback convention, while a detail route opts into previous-value retention because preserving the record during refresh is important there. A component-level scope can then choose a different policy for a compact widget without changing the resource factory used elsewhere.
Scope is the main reason to consider the provider API instead of attaching extensions ad hoc. It makes the policy discoverable at the injector boundary, but it also means developers must understand which provider wins when parent and child scopes differ. Document the convention in the feature so a component’s displayed value is not surprising to someone who only sees the resource declaration.
What happens when reactive request inputs change?
Angular’s resource model treats a changed request as a new load. For httpResource(), a pending request is cancelled before the new one is issued; resources can also cancel work when they are destroyed. This prevents an obsolete response from winning a race against the current request.
Cancellation does not decide what the user sees between requests. With native semantics, the value may be unavailable during the new load, so the template should use isLoading, status, and hasValue deliberately. With a previous-value extension, the old result remains available, but the UI should still expose that a refresh is underway.
Is NgRx Resource Extensions stable?
Angular’s API references identify Resource, resource(), httpResource(), and rxResource() as stable in Angular v22; the rxResource() reference specifically marks it stable since v22.0. NgRx’s Resource Extensions are documented as experimental.
Experimental status does not make the extensions unusable, but it changes the decision. A team should budget time for API adjustments during NgRx upgrades, isolate extension usage behind a small local abstraction when practical, and avoid making every feature depend on experimental behavior unless the UX benefit is material. If the application can meet its needs with Angular’s stable lifecycle signals and explicit guards, the native path has less upgrade risk.
What is the safest adoption path?
- Inventory each asynchronous read and classify its loader as custom, HTTP, or Observable-based.
- Use
resource(),httpResource(), orrxResource()without extensions first. - Record where a blank value during refresh creates a real usability problem, rather than assuming every screen needs stale data.
- For those screens, choose one policy: previous value, loading fallback, previous value on error, or error fallback.
- Apply the policy locally with
extendResourceor register it withprovideResourceExtensions()when a whole injector scope shares the rule. - Keep writes in
HttpClientor a command API, then explicitly coordinate the next read. - Test both the lifecycle and the displayed value: initial load, refresh, cancellation after a request change, successful completion, and failure.
- Because NgRx extensions are experimental, pin compatible versions and review release notes before upgrading Angular or NgRx.
Decision checklist
- Need an ordinary signal read? Start with Angular Resource.
- Need an HTTP read? Prefer
httpResource()for interceptor and testing integration. - Already have an Observable loader? Use
rxResource(). - Need the last value during refresh or failure? Add the corresponding NgRx extension.
- Need a known value shape while loading or failing? Use a configured fallback extension.
- Need application, route, or component defaults? Consider
provideResourceExtensions(). - Need POST or PUT? Use
HttpClientor another command-oriented API. - Cannot accept experimental dependencies? Stay with Angular’s native semantics and guard reads with
hasValue().
Frequently Asked Questions
Does keeping the previous value mean Angular caches the response?
The extension controls the value exposed while a reload or error is active; it is not described as a persistent cache or cross-request storage mechanism. Treat retention as a presentation policy tied to that Resource’s lifetime, and use a dedicated cache when data must survive destruction or be shared independently.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →How should a template read a resource after an error?
With native Angular semantics, check hasValue() before reading value(), because reading the value in an error state can throw. An error extension can provide a retained or fallback value, but the template should still expose the failure through the resource’s status or error state.
Can I combine an NgRx extension with an HTTP resource and interceptors?
Yes. The extension wraps the existing Resource rather than replacing its specialized type, so an httpResource() continues to use Angular’s HttpClient pipeline. Interceptors and HTTP testing support remain properties of the underlying resource.
Can different routes use different loading policies?
Yes. provideResourceExtensions() supports application, route, and component injector scopes, and child scopes can refine parent defaults. This allows a feature that needs stale-value retention to opt in without forcing that behavior on every screen.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

