Ng-News 25/09: Angular 19.2, httpResource

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))
  })
}        
// 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}`)
  })
}        
// with Angular 19.2

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

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

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();
  }
}        

2. 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()}`)
  }
}        

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 })
}        

4. default value and no eagerly-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();
  }
}        

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.


要查看或添加评论,请登录

Rainer Hahnekamp的更多文章