DEV Community

Cover image for Ng-News 25/09: Angular 19.2, httpResource
ng-news for This is Angular

Posted on

Ng-News 25/09: Angular 19.2, httpResource

Angular 19.2 is here, and the standout feature is the experimental httpResource.

Previously, triggering an HTTP request based on a Signal change required using an effect. With Angular 19.0, resource provided a structured way to handle asynchronous data, but httpResource is the dedicated solution for handling HTTP requests in a reactive manner.

// 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

How does it work?

Instead of manually managing requests, httpResource integrates seamlessly with Signals. By passing one or multiple Signals into the url parameter, it automatically executes an HTTP request whenever their values change. The result is stored in a Signal, which is the value of quiz in the example.

resource and rxResource remain foundational for handling asynchronous tasks in Angular. HTTP requests make up the majority of such operations. That’s why httpResource is set to become the preferred tool for data fetching. Although 19.2 is a minor release, its impact is significant.

Key aspects of httpResource

1. No replacement for HttpClient

It is optimized for reactive data fetching but does not replace HttpClient for mutations (POST, PUT, DELETE).

 // 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. Eagerly/(Pre)-fetching as default behavior

In contrast to Observables, which request lazily, i.e. upon subscription, httpResource fetches eagerly. So even before it is needed.

// 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. parse built-in

It introduces a more flexible approach to type handling, allowing the use of a parse function (e.g., with Zod) for runtime validation and stronger type safety.

// 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. default value and no eager-fetching

Developers can define default values, manually trigger requests, or delay execution by returning undefined. However, if the request resolves to undefined, .reload() will not function.

// 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

Beyond 19.2: The Future of Resources

Alongside the release, the Angular team published two RFCs. The first discusses the motivation behind resource, alternative approaches (such as suspense-based handling), and potential future integrations, including routing, SSR, and error handling.

The second RFC details the API design for resource, rxResource, and httpResource. The team is actively seeking feedback (just saying).

There is already extensive community coverage of httpResource, with some of it featured in previous episodes. However, for a deeper understanding, the RFCs remain the primary reference.

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

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

Top comments (0)