I am learning about httpResource
and I can notice that the httpResource
signal is not firing when the signal used to generate the URL is changed.
Angular.dev - HttpResource Docs
Below is a simple example highlighting my challenge.
@Component({
selector: 'app-root',
imports: [FormsModule, CommonModule],
template: `
<input [(ngModel)]="id" type="number"/>
<hr/>
<div>{{api.value() | json}}</div>
`,
})
export class App {
id = signal<number>(2);
api = httpResource(`https://jsonplaceholder.typicode.com/todos/${this.id()}`);
}
Angular version: 19
When I raised a feature request Enable url property of HttpResourceRequest to be a callback #60962 for converting url
to callback, I was pointed out the below PR
refactor(http): remove non reactive signature from httpResource. #60537
So the below usage, will no longer be possible as of Angular 20:
api = httpResource(`https://jsonplaceholder.typicode.com/todos/${this.id()}`); // Angular 20 ❌
You must use a callback
, so reactivity will be the default as of Angular 20:
api = httpResource(() => `https://jsonplaceholder.typicode.com/todos/${this.id()}`); // Angular 20 ✅
When we look at the url
property of HttpResource
, we can observe the below.
url
property as string
:url
string you have passed inside will be fetched only once during initialization.httpResource
does not refresh.id = signal<number | undefined>(2);
api = httpResource(`https://jsonplaceholder.typicode.com/todos/${this.id()}`);
url
property as callback which return a string:url
string you have passed inside will be fetched during initialization.httpResource
will also refresh.id = signal<number | undefined>(2);
api = httpResource(() => `https://jsonplaceholder.typicode.com/todos/${this.id()}`);
url
property as callback, when you want reactivity. Pass the url
property as string, when you just want to fetch a static URL, which does not need reactivity.The solution to your problem is to convert the url
property to a callback, then reactivity will start working.
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import {
httpResource,
HttpResourceOptions,
HttpResourceRequest,
provideHttpClient,
} from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'app-root',
imports: [FormsModule, CommonModule],
template: `
<input [(ngModel)]="id" type="number"/>
<hr/>
<div>{{api.value() | json}}</div>
`,
})
export class App {
id = signal<number>(2);
api = httpResource(
() => `https://jsonplaceholder.typicode.com/todos/${this.id()}`
);
}
bootstrapApplication(App, {
providers: [provideHttpClient()],
});