Angular 16+ (Resource API: Angular 19+)
Table of Contents
- The What and Why of Signals
- Creating and Reading Signals
- computed() and linkedSignal()
- Fetching Data into a Signal
- Fetching Data Reactively
- Quick Reference for Signals APIs
1. The What and Why of Signals
What is a Signal?
A signal is a container that holds a value. Unlike a regular variable, a signal notifies its consumers when its value changes.
💡 Metaphor: think of a signal as a light box. You put a value in the box. When the value changes, the box lights up — that is the change notification.
Instead of declaring classic variables:
let title = 'Acme Inventory Suite';
let itemCount = 1;
You declare signals:
import { signal } from '@angular/core';
title = 'Acme Inventory Suite'; // not a signal, constant value
itemCount = signal(1); // signal with initial value
Signals are the recommended approach for defining and managing data (state) in Angular applications, particularly when:
- The data is displayed in the UI and must trigger a re-render when it changes.
- It is used in computations that should be recalculated automatically.
Why Use Signals?
Three main reasons:
- Increased reactivity — Code reacts automatically to data changes.
- Improved change detection — Angular tracks more precisely what changed in the template.
- Simplified code — Less boilerplate compared to RxJS/Observables.
Illustration: the problem with classic variables
// Classic variables — NOT reactive
let x = 5;
let y = 3;
let z = x + y; // z = 8
x = 10;
console.log(z); // still 8 !! z does NOT react to the change in x
The solution with Signals
import { signal, computed } from '@angular/core';
const x = signal(5);
const y = signal(3);
const z = computed(() => x() + y()); // z is REACTIVE
console.log(z()); // 8
x.set(10);
console.log(z()); // 13 — recalculated automatically!
flowchart LR
X["signal x\n(value: 10)"] -->|dependency| Z
Y["signal y\n(value: 3)"] -->|dependency| Z
Z["computed z\n= x() + y()\n(value: 13)"]
Z -->|re-render| UI["Template / UI"]
Signals and Change Detection
Before signals, Angular used zone.js to detect changes (by patching browser async APIs and checking the entire component tree). This is inefficient.
With signals:
- Angular knows exactly which signal changed.
- Only the piece of the template that reads that signal is re-rendered.
- Future possibility to drop
zone.jsentirely (zoneless mode).
flowchart TB
subgraph "Without Signals (zone.js)"
A1[User action] --> B1[zone.js detects]
B1 --> C1[Full check\nof component tree]
C1 --> D1[Potentially re-renders\nthe entire component]
end
subgraph "With Signals"
A2[User action] --> B2[Signal changes]
B2 --> C2[Angular knows which\nsignal changed]
C2 --> D2[Targeted re-render\nof the relevant UI fragment]
end
What Data Should Be Signals?
Best practices — YES, a signal
| Condition | Example |
|---|---|
| Value in the UI can change | products, selectedProduct, itemCount |
| Value must react and recalculate when another signal changes | total (price × quantity) |
| Value is shared between components | Declare in a service |
Best practices — NO, not a signal
| Condition | Example |
|---|---|
| Constant value | Page title that never changes |
| Local variable not used in the UI | Boolean flag local to a method |
| Events (actions that occur) | (click), (change) |
| Asynchronous operations themselves | HTTP requests directly (but their result can be via httpResource) |
Signals are synchronous by nature.
Analysis example for a product application
graph TD
APP[Product Management Application]
APP -->|signal WritableSignal| P["products\nWritableSignal<Product[]>"]
APP -->|signal WritableSignal| SP["selectedProduct\nWritableSignal<Product | undefined>"]
APP -->|linkedSignal WritableSignal| Q["quantity\nWritableSignal<number>"]
APP -->|signal WritableSignal| R["reviews\nWritableSignal<Review[]>"]
APP -->|computed Signal readonly| T["total\nSignal<number> (readonly)"]
APP -->|simple variable| TT["pageTitle\nstring (not a signal)"]
SP -->|dependency| T
Q -->|dependency| T
Summary — What, Why, Which
| Aspect | Detail |
|---|---|
| What a signal is | Value container + automatic change notification |
| Available since | Angular v16 |
| Benefits | Reactivity, improved change detection, simplified code |
| What to put in a signal | Any UI value that can change, any reactive value |
| What NOT to put | Constants, local variables, events, async operations themselves |
2. Creating and Reading Signals
Basic Signal Syntax
Creating a signal
import { signal } from '@angular/core';
// General syntax
// The generic type is often inferred, but can be explicit
signalName = signal<Type>(initialValue);
// Examples
itemCount = signal(1); // inferred: WritableSignal<number>
label = signal<string>('Hello World'); // explicit: WritableSignal<string>
⚠️ A signal must always have an initial value — this is mandatory.
Reading a signal
// In the component TypeScript
const value = this.itemCount(); // parentheses = "opening the box"
// In the HTML template
{{ itemCount() }} // interpolation
[value]="itemCount()" // property binding
💡 Mnemonic: the parentheses open the box to read the current value.
Important behaviors
- A signal holds only one value — the current value.
- Reading a signal in a template registers that signal as a dependency of the view → automatic re-render when the signal changes.
- Reading a signal in a reactive function (such as
computed) registers it as a dependency of that function. computedvalues are memoized: the result is reused until a dependency changes.
sequenceDiagram
participant Template
participant Signal
participant Angular
Template->>Signal: signal() — read
Signal-->>Template: current value
Signal->>Angular: registers Template as dependent
Note over Signal,Angular: Later...
Signal->>Signal: value changes (set/update)
Signal->>Angular: change notification
Angular->>Template: re-render of the relevant fragment
Create and Read a Signal — Demo
Demo application structure (APM — Acme Product Management):
src/app/
├── app.component.ts / .html
├── products/
│ ├── product.ts (Product interface)
│ ├── product-data.ts (static data)
│ ├── product.service.ts
│ └── product-selection/
│ ├── product-selection.component.ts
│ └── product-selection.component.html
└── reviews/
├── review.ts (Review interface)
├── review.service.ts
└── review-list/
├── review-list.component.ts
└── review-list.component.html
Example of a simple signal in a component:
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-product-selection',
templateUrl: './product-selection.component.html'
})
export class ProductSelectionComponent {
// Writable signal for quantity
quantity = signal(1);
}
In the template:
<!-- Reading the signal with parentheses -->
<p>Quantity: {{ quantity() }}</p>
<!-- Two-way binding with a signal -->
<input type="number" [(ngModel)]="quantity" />
Signals with Arrays
import { Component, signal } from '@angular/core';
import { Product } from '../product';
import { ProductData } from '../product-data';
@Component({ /* ... */ })
export class ProductSelectionComponent {
// Signal holding an array of products
products = signal<Product[]>(ProductData.products);
// WritableSignal<Product[]>
}
In the template — using the @for control flow:
<select>
<option [ngValue]="undefined">-- Select a product --</option>
@for (product of products(); track product.id) {
<option [ngValue]="product">{{ product.productName }}</option>
}
</select>
products()— the parentheses are required to read the signal’s value in the template.
Signals with Objects
import { Component, signal } from '@angular/core';
import { Product } from '../product';
@Component({ /* ... */ })
export class ProductSelectionComponent {
// Signal for the selected product — may be undefined initially
selectedProduct = signal<Product | undefined>(undefined);
// WritableSignal<Product | undefined>
}
In the template — safe navigation operator to handle undefined:
<!-- ?.productName avoids an error if selectedProduct() is undefined -->
<h2>{{ selectedProduct()?.productName }}</h2>
<p>{{ selectedProduct()?.description }}</p>
<p>Price: {{ selectedProduct()?.price | currency }}</p>
Two-way binding on the <select> to update the signal automatically:
<select [(ngModel)]="selectedProduct">
<option [ngValue]="undefined">-- Select --</option>
@for (product of products(); track product.id) {
<option [ngValue]="product">{{ product.productName }}</option>
}
</select>
Modifying a Signal’s Value: set() and update()
Two methods to modify a WritableSignal:
| Method | Usage | Example |
|---|---|---|
set(value) | Sets a new absolute value | quantity.set(5) |
update(fn) | Computes the new value from the current value | quantity.update(q => q + 1) |
export class ProductSelectionComponent {
quantity = signal(1);
onIncrease(): void {
// update receives the current value and returns the new value
this.quantity.update(q => q + 1);
}
onDecrease(): void {
// Guard to prevent going below 1
this.quantity.update(q => (q > 1 ? q - 1 : 1));
}
}
In the template:
<button (click)="onDecrease()">-</button>
<input type="number" [(ngModel)]="quantity" />
<button (click)="onIncrease()">+</button>
💡 Use
update()when the new value depends on the current value.
Useset()when the new value is independent.
effect() and Debugging Tips
An effect runs code every time one or more signals it depends on change. An excellent technique for debugging.
import { Component, signal, effect } from '@angular/core';
@Component({ /* ... */ })
export class ProductSelectionComponent {
quantity = signal(1);
// Debug effect — logs the quantity on every change
qtyEffect = effect(() => {
console.log('quantity:', this.quantity()); // () to read the signal
});
}
Important behavior of effect()
Effects are scheduled, not immediate. They wait their turn to execute.
onIncrease(): void {
this.quantity.set(2);
this.quantity.set(42);
this.quantity.set(12);
// The effect will only see the final value: 12
// It runs only once the method has completed
}
sequenceDiagram
participant Method
participant Signal
participant EffectScheduler
participant Effect
Method->>Signal: set(2)
Method->>Signal: set(42)
Method->>Signal: set(12)
Method-->>EffectScheduler: method done, run the effect
EffectScheduler->>Effect: executes
Effect->>Signal: quantity() → reads 12
Effect-->>Console: log "quantity: 12"
Other use cases for effect()
- Syncing data with
localStorage. - Triggering an animation when a signal changes.
- Logging metrics or analytics events.
⚠️ Avoid modifying other signals inside an
effect— this can create cycles. Prefercomputed()for derivations.
3. computed() and linkedSignal()
computed() Signal
A computed signal performs an automatic computation when its dependent signals change. Its result is read-only (Signal<T>, not WritableSignal<T>).
import { signal, computed } from '@angular/core';
const price = signal(29.99);
const quantity = signal(3);
// computed = reactive derivation, read-only
const total = computed(() => price() * quantity());
// Signal<number> — not WritableSignal
console.log(total()); // 89.97
quantity.set(5);
console.log(total()); // 149.95 — recalculated automatically
Characteristics of computed()
| Characteristic | Detail |
|---|---|
| Read-only | Cannot call .set() or .update() |
| Memoization | Result is cached; recomputes only if a dependency changes |
| Lazy | Only recomputes if something reads the signal and a dependency has changed |
| Auto dependencies | Every signal read inside the function becomes a dependency |
flowchart LR
SP["selectedProduct\nWritableSignal"] -->|dependency| T
Q["quantity\nWritableSignal"] -->|dependency| T
T["total\ncomputed Signal\n(readonly)"] -->|display| UI["Template UI"]
T -->|conditional color| COLOR["totalColor\ncomputed Signal\n(readonly)"]
Create a computed() Signal — Demo
import { Component, signal, computed } from '@angular/core';
import { Product } from '../product';
@Component({ /* ... */ })
export class ProductSelectionComponent {
selectedProduct = signal<Product | undefined>(undefined);
quantity = signal(1);
// computed — totals price × quantity
total = computed(() =>
(this.selectedProduct()?.price ?? 0) * this.quantity()
);
// computed for conditional total color
totalColor = computed(() =>
this.total() > 100 ? 'text-danger' : 'text-success'
);
}
In the template:
<tr>
<td>Total</td>
<td [class]="totalColor()">
{{ total() | currency }}
</td>
</tr>
??is the nullish coalescing operator: if the left side isnullorundefined, it uses the right-side value (here0).
linkedSignal()
A linkedSignal creates a writable signal that resets automatically when its dependent signals change. It is the combination of WritableSignal + automatic reactivity.
Typical use case
When a new product is selected, the quantity should reset to 1 — but the user should also be able to modify it manually.
computeddoesn’t work here → read-only, two-way binding not possible.linkedSignalis a perfect fit → writable AND reactive.
Syntax 1 — Simple reactive function
import { signal, linkedSignal } from '@angular/core';
const gameReset = signal(false);
// Resets to 0 when gameReset changes
const score = linkedSignal(() => (gameReset() ? 0 : 10));
// WritableSignal<number>
Syntax 2 — Object with source and computation
import { signal, linkedSignal } from '@angular/core';
const selectedProduct = signal<Product | undefined>(undefined);
// quantity resets to 1 each time selectedProduct changes
const quantity = linkedSignal<Product | undefined, number>({
source: selectedProduct, // trigger signal
computation: (p, previous) => 1 // always reset to 1
// 'p' = current value of the source
// 'previous.value' = previous value of the linkedSignal (if needed)
});
sourcereceives the signal itself (without parentheses), not its value.
Using the previous value
const quantity = linkedSignal<Product | undefined, number>({
source: selectedProduct,
computation: (newProduct, previous) => {
// Can access previous.value (old quantity)
// and previous.source (old product)
return previous?.value ?? 1;
}
});
Create a linkedSignal() — Demo
import { Component, signal, computed, linkedSignal } from '@angular/core';
import { Product } from '../product';
@Component({ /* ... */ })
export class ProductSelectionComponent {
selectedProduct = signal<Product | undefined>(undefined);
// linkedSignal: writable AND resets when selectedProduct changes
quantity = linkedSignal({
source: this.selectedProduct,
computation: () => 1 // no need for the previous value here
});
// Still WritableSignal<number> — two-way binding still works
total = computed(() =>
(this.selectedProduct()?.price ?? 0) * this.quantity()
);
}
<!-- quantity is still writable, two-way binding works -->
<input type="number" [(ngModel)]="quantity" min="1" />
computed() vs linkedSignal() — When to Use Which?
flowchart TD
Q{Need to write\nto the signal?}
Q -->|No| C["computed()\nRead-only\nPure derivation"]
Q -->|Yes| R{Need to reset when\nanother signal changes?}
R -->|No| W["signal() ordinary\nWritableSignal"]
R -->|Yes| L["linkedSignal()\nWritable + Reactive"]
C --> CE["Examples:\n• total = price × qty\n• totalColor\n• isValid"]
L --> LE["Examples:\n• quantity resets on product change\n• selection preserved after refresh"]
| Criterion | computed() | linkedSignal() |
|---|---|---|
| Writable | ❌ No | ✅ Yes |
| Reactive | ✅ Yes | ✅ Yes |
| Access previous value | ❌ No | ✅ Yes (previous.value) |
| Two-way binding | ❌ No | ✅ Yes |
| Typical usage | Derived calculations, colors, validations | Selection reset, default quantity |
When to pass a reactive function vs an object to linkedSignal:
- Reactive function: when the function directly references all dependent signals.
- Object
{ source, computation }: when the computation does not directly access the signals, or when you needprevious.value/previous.source.
4. Fetching Data into a Signal
Observable vs httpResource()
Before Angular 19, fetching HTTP data and placing it in a signal was cumbersome:
// BEFORE Angular 19 — Observable approach (complex)
products = signal<Product[]>([]);
constructor(private http: HttpClient) {
this.http.get<Product[]>(this.productsUrl)
.pipe(takeUntilDestroyed())
.subscribe(data => {
this.products.set(data); // manual signal update
});
}
With Angular 19+, the Resource API radically simplifies this:
// AFTER Angular 19 — httpResource (simple)
productsResource = httpResource<Product[]>(() => this.productsUrl);
// No subscribe, no unsubscribe, no Observable
flowchart LR
subgraph "Before Angular 19"
A1[httpClient.get] --> B1[Observable]
B1 -->|subscribe| C1[callback]
C1 -->|manual set| D1[signal]
D1 --> UI1[UI]
C1 -.->|do not forget| UNS1[unsubscribe]
end
subgraph "With httpResource Angular 19+"
A2[httpResource] -->|automatic| D2[ResourceRef\n.value signal]
D2 --> UI2[UI]
end
Fetching Data with httpResource() — Demo
import { Injectable } from '@angular/core';
import { httpResource } from '@angular/common/http';
import { Product } from './product';
@Injectable({ providedIn: 'root' })
export class ProductService {
private productsUrl = 'https://api.example.com/products';
// Declares the resource — the HTTP request is issued automatically
productsResource = httpResource<Product[]>(
() => this.productsUrl,
{ defaultValue: [] } // avoids handling undefined everywhere
);
// HttpResourceRef<Product[]>
}
In the component:
import { Component, inject } from '@angular/core';
import { ProductService } from '../product.service';
@Component({ /* ... */ })
export class ProductSelectionComponent {
private productService = inject(ProductService);
// Accesses the resource's value signal
products = this.productService.productsResource.value;
// Signal<Product[]>
}
In the template:
@for (product of products(); track product.id) {
<option [ngValue]="product">{{ product.productName }}</option>
}
Properties of an HttpResourceRef
| Property | Type | Description |
|---|---|---|
.value | Signal<T> | The returned data (writable) |
.isLoading | Signal<boolean> | true during the request |
.error | Signal<Error | undefined> | Error if the request fails |
.status | Signal<ResourceStatus> | Detailed request status |
.reload() | method | Re-issues the HTTP request |
Returning a Resource from a Method
There are two patterns for declaring a resource:
Pattern 1 — Direct declaration in the service (recommended for sharing)
@Injectable({ providedIn: 'root' })
export class ProductService {
// Resource created at service initialization
// Lives as long as the service → shared data
productsResource = httpResource<Product[]>(
() => this.productsUrl,
{ defaultValue: [] }
);
}
Pattern 2 — Factory method in the service (for component lifecycle)
@Injectable({ providedIn: 'root' })
export class ProductService {
createProducts() {
// Resource created when the method is called
return httpResource<Product[]>(
() => this.productsUrl,
{ defaultValue: [] }
);
}
}
// In the component
export class ProductSelectionComponent {
private productService = inject(ProductService);
// Resource created when the component initializes
// Destroyed when the component is destroyed
productsResource = this.productService.createProducts();
}
Choosing the right pattern:
| Criterion | Service (Pattern 1) | Factory (Pattern 2) |
|---|---|---|
| Lifetime | Entire service lifetime | Tied to component lifecycle |
| Sharing | Multiple components | Single component |
| HTTP request | Issued once | Re-issued on every navigation to the component |
| Usage | Reference lists, permanent data | View-specific data |
Resource Properties: isLoading and error
@Component({ /* ... */ })
export class ProductSelectionComponent {
private productService = inject(ProductService);
// Access resource properties
isLoading = this.productService.productsResource.isLoading;
// Signal<boolean>
private error = this.productService.productsResource.error;
// Signal<Error | undefined>
// Computed to transform the error into a readable message
errorMessage = computed(() =>
this.error()?.message ?? ''
);
}
In the template:
@if (isLoading()) {
<p class="text-info">Loading products...</p>
}
@if (errorMessage()) {
<p class="text-danger">{{ errorMessage() }}</p>
}
@if (!isLoading() && !errorMessage()) {
<!-- Normal product display -->
<select [(ngModel)]="selectedProduct">
@for (product of products(); track product.id) {
<option [ngValue]="product">{{ product.productName }}</option>
}
</select>
}
Frequently Asked Questions about the Resource API
Where should resources be declared?
- In a service if the data needs to be shared or persist after the component is destroyed.
- In a component (via service factory method) if only one view uses the data and the lifecycle should follow the component.
Can I use my HTTP interceptors?
- ✅ Yes.
httpResourceusesHttpClientinternally, interceptors work normally.
Can I use the Resource API for mutations (POST, PUT, DELETE)?
- ❌ No. The Resource API is only for fetching data (GET). Its request cancellation handling is not suited for mutations. Continue using
HttpClientdirectly for write operations.
What resource types exist?
| Resource | Base | Usage |
|---|---|---|
httpResource() | HttpClient | Simple HTTP fetching (JSON, blob, text…) |
resource() | Promises | Low-level, with Promises |
rxResource() | RxJS Observables | When RxJS operators are needed (merge, forkJoin, etc.) |
5. Fetching Data Reactively
Sharing Data in a Service
For ReviewService to fetch reviews for the selected product, it needs access to the selectedProduct signal. That signal must therefore be in a shared service.
Moving signals to the service:
import { Injectable, signal, computed, linkedSignal } from '@angular/core';
import { httpResource } from '@angular/common/http';
import { Product } from './product';
@Injectable({ providedIn: 'root' })
export class ProductService {
private productsUrl = 'https://api.example.com/products';
// Resource for products
productsResource = httpResource<Product[]>(
() => this.productsUrl,
{ defaultValue: [] }
);
// Shared signal — accessible by any component/service
selectedProduct = signal<Product | undefined>(undefined);
// linkedSignal — reset when selectedProduct changes
quantity = linkedSignal({
source: this.selectedProduct,
computation: () => 1
});
// computed — total calculated reactively
total = computed(() =>
(this.selectedProduct()?.price ?? 0) * this.quantity()
);
}
Reactive Data Fetching — Demo
The ReviewService injects ProductService and uses selectedProduct as a dependent signal in the resource:
import { Injectable, inject, effect } from '@angular/core';
import { httpResource } from '@angular/common/http';
import { ProductService } from '../products/product.service';
import { Review } from './review';
@Injectable({ providedIn: 'root' })
export class ReviewService {
private reviewsUrl = 'https://api.example.com/reviews';
private productService = inject(ProductService);
// Reactive resource — re-issues the request each time selectedProduct changes
reviewsResource = httpResource<Review[]>(
() => {
const p = this.productService.selectedProduct();
if (!p) return undefined; // no request if no product is selected
// Template literal to build the URL with a query parameter
return `${this.reviewsUrl}?productId=^${p.id}$`;
// ^ and $ = regex for exact ID match
},
{ defaultValue: [] }
);
// Debug effect
loadingEffect = effect(() => {
console.log('loading reviews:', this.reviewsResource.isLoading());
});
}
sequenceDiagram
participant User
participant Component
participant ProductService
participant ReviewService
participant API
User->>Component: Selects a product
Component->>ProductService: selectedProduct.set(product)
ProductService-->>ReviewService: signal change detected
ReviewService->>ReviewService: arrow function re-executed
ReviewService->>API: GET /reviews?productId=^5$
API-->>ReviewService: [review1, review2, ...]
ReviewService-->>ReviewService: reviewsResource.value.set(reviews)
ReviewService-->>Component: reviews signal updated
Component-->>User: Displays reviews
Handling Undefined and Passing Parameters with httpResource()
Returning undefined to block the request
reviewsResource = httpResource<Review[]>(
() => {
const p = this.productService.selectedProduct();
// If no product is selected → undefined → no HTTP request
if (!p) return undefined;
return `${this.reviewsUrl}?productId=^${p.id}$`;
},
{ defaultValue: [] }
);
Passing parameters via an options object
reviewsResource = httpResource<Review[]>(
() => {
const p = this.productService.selectedProduct();
if (!p) return undefined;
// Alternative: HttpRequest options object
return {
url: this.reviewsUrl,
params: { productId: `^${p.id}$` }
};
},
{ defaultValue: [] }
);
httpResource() Features and Suggestions
Controlling request triggering
// Gate signal — triggers the request only on user action
loadCatalogNow = signal(false);
productsResource = httpResource<Product[]>(
() => {
if (!this.loadCatalogNow()) return undefined;
return this.productsUrl;
},
{ defaultValue: [] }
);
// In a handler
onLoadProducts(): void {
this.loadCatalogNow.set(true);
}
Manual reload
// Reload data after a delay or on user demand
this.productsResource.reload();
Fetching different data types
// JSON (default)
httpResource<Product[]>(() => url)
// Text
httpResource.text(() => url)
// Blob (images, files)
httpResource.blob(() => url)
// ArrayBuffer
httpResource.arrayBuffer(() => url)
Signals in other Angular features
| Feature | Signal API | Availability |
|---|---|---|
| Component input | input(), input.required() | Angular 17+ |
| Two-way parent binding | model() | Angular 17+ |
| DOM query | viewChild(), contentChild() | Angular 17+ |
| Routing | toSignal(activatedRoute.params) | Angular 16+ |
| Output | output() | Angular 17+ |
6. Quick Reference for Signals APIs
Complete Reference Table
| API | Import | Returned Type | Writable | Description |
|---|---|---|---|---|
signal(value) | @angular/core | WritableSignal<T> | ✅ | Creates a mutable signal |
computed(() => ...) | @angular/core | Signal<T> (readonly) | ❌ | Reactive calculated derivation |
linkedSignal(...) | @angular/core | WritableSignal<T> | ✅ | Writable + resettable |
effect(() => ...) | @angular/core | EffectRef | — | Reactive side effects |
toSignal(obs$) | @angular/core/rxjs-interop | Signal<T> | ❌ | Converts an Observable to a Signal |
toObservable(sig) | @angular/core/rxjs-interop | Observable<T> | — | Converts a Signal to an Observable |
httpResource(fn) | @angular/common/http | HttpResourceRef<T> | — | HTTP fetching into a signal |
WritableSignal Methods
| Method | Description | Example |
|---|---|---|
signal() | Reads the current value | quantity() → 3 |
.set(val) | Sets a new value | quantity.set(5) |
.update(fn) | Computes new value from the old one | quantity.update(q => q + 1) |
.asReadonly() | Returns a read-only version | quantity.asReadonly() |
HttpResourceRef Properties
const resource = httpResource<T[]>(() => url, { defaultValue: [] });
resource.value // Signal<T[]> — the data
resource.isLoading // Signal<boolean> — loading indicator
resource.error // Signal<Error | undefined> — potential error
resource.status // Signal<ResourceStatus> — detailed status
resource.reload() // void — re-issues the request
Search Terms
angular · signals · frontend · development · signal · data · computed · fetching · httpresource · linkedsignal · effect · properties · resource · service · syntax · features · httpresourceref · important · method · object · parameters · passing · pattern · reactive