Angular 19.2 Brings Experimental httpResource

Angular 19.2 has shipped, with the experimental httpResource as the headline feature.

In earlier versions, firing an HTTP request after a Signal changed meant reaching for an effect. Angular 19.0 then introduced resource, giving developers a structured way to manage async data. Now, httpResource arrives as the purpose-built option for handling HTTP in a reactive style.

// before Angular 19
export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  quiz = signal<Quiz | undefined>(undefined);

  httpClient = inject(HttpClient)
  quizLoadEffect = effect(async () => {
    this.httpClient.get<Quiz>(`someurl/${this.id()}`).subscribe(quiz =>
      this.quiz.set(quiz))
  })
}
Enter fullscreen mode Exit fullscreen mode
// with Angular 19.0

export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  httpClient = inject(HttpClient);
  quiz = rxResource({
    request: this.id,
    loader: ({request}) => this.httpClient.get<Quiz>(`someurl/${request}`)
  })
}
Enter fullscreen mode Exit fullscreen mode
// with Angular 19.2

export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  quiz = httpResource<Quiz>(() => `someurl/${this.id()}`)
}
Enter fullscreen mode Exit fullscreen mode

Under the Hood

Rather than orchestrating requests manually, httpResource fits cleanly into the Signals model. When one or more Signals are handed to the url parameter, the URL re-request runs automatically as those Signal values shift. The outcome lands in a Signal, exposed as the value property of quiz in the illustration.

Both resource and rxResource still serve as the backbone for async work in Angular. Data fetching via HTTP accounts for the lion's share of those tasks, which positions httpResource as the likely go-to for API calls going forward. Even as a minor release, 19.2 carries substantial weight.

What Stands Out in httpResource

1. It is not a replacement for HttpClient

The utility shines for reactive reads but is not intended to take over write operations—POST, PUT, DELETE still belong to HttpClient.

 // we don't use httpResource for mutations

export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  quiz = httpResource<Quiz>(() => `someurl/${this.id()}`)


  httpClient = inject(HttpClient)
  saveAnswer(answerId: number){ 
    this.httpClient.post('someurl', {answerId}).subscribe();
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Fetching starts right away by default

Observables hold off until someone subscribes—lazy by nature. httpResource flips that: it goes out and fetches immediately, even if the result is not yet required.

// Even if it is not used, it fetches eagerly

export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  constructor() {
    httpResource<Quiz>(() => `someurl/${this.id()}`)
  }
}
Enter fullscreen mode Exit fullscreen mode

3. A built-in parse hook

Type management gets more flexible with a dedicated parse function. Tools like Zod can slot in here, providing runtime checks and tighter type guarantees.

// This example uses zod for runtime type validation

export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  quizSchema = z.object({
    name: z.string(),
    timeInSeconds: z.number()
  })


  quiz = httpResource(() => `someurl/${this.id()}`,
    { parse: this.quizSchema.parse })
}
Enter fullscreen mode Exit fullscreen mode

4. Defaults and deferred fetching

Setting an initial value is supported, as is kicking off requests by hand or stalling them by yielding undefined. One caveat: when the response itself turns out to be undefined, .reload() will not work as expected.

// Using default value and request only when `refresh` is called

export class QuizComponent {
  id = input.required({ transform: numberAttribute });

  quizSchema = z.object({
    name: z.string(),
    timeInSeconds: z.number()
  })


  isQuizActive = signal(false)
  quiz = httpResource(() => this.isQuizActive() ? `someurl/${this.id()}` : undefined,
    {
      parse: this.quizSchema.parse,
      defaultValue: { name: '', timeInSeconds: 0 }
    })

  refresh() {
    this.isQuizActive.set(true);
    this.quiz.reload();
  }
}
Enter fullscreen mode Exit fullscreen mode

Looking Past 19.2: Resources Ahead

The Angular team paired the release with two RFCs. The first digs into why resource exists, contrasts it with alternate strategies like suspense, and maps out future directions such as routing, SSR, and error handling.

The second RFC lays out the API blueprint for resource, rxResource, and httpResource. Input from the community is explicitly being solicited—in case that was not clear.

Plenty of blog posts and discussions around httpResource are already circulating, some highlighted in earlier installments. For the full picture, though, the RFCs are the definitive source.

RFC 1: https://github.com/angular/angular/discussions/60120

RFC 2: https://github.com/angular/angular/discussions/60121