How to set a timeout config for lastValueFrom() using RxJS 7 in Angular 13?

3.3k Views Asked by At

Quote from RxJS dev team:

To fix all these issues, we decided to deprecate toPromise(), and to introduce the two new helper functions for conversion to Promises.

Use one of the two new functions

As a replacement to the deprecated toPromise() method, you should use one of the two built in static conversion functions firstValueFrom or lastValueFrom....

In my case I send a get request to the server to check if the server is available or not. The main function (in this case the ngOnInit()) will not go further until an HTTP response or an error comes back.

At this part of the article, they suggest adding a timeout to the lastValueFrom() function, which should be added as a config config?: LastValueFromConfig<D>.

My code:

    let something = lastValueFrom(this.http.get<resultDTO> 
    ('/api/account/test'),).then(
          res => {
            this.note = (res.data);
          }
    );

How do I have to set this config and pass it to the function?

1

There are 1 best solutions below

3
On

The timeout operator must be added to the HTTP request and not the Promise from lastValueFrom.

let something = lastValueFrom(
  this.http.get<resultDTO>('/api/account/test').pipe(
    timeout(5000)      // <-- HTTP request will error out if no response for 5 seconds
  )
).then(res => {
  this.note = (res.data);
});

The LastValueFromConfig argument at the moment (RxJS v7) has only one value.

export interface LastValueFromConfig<T> {
  defaultValue: T;
}

This has nothing to do with the timeout behaviour of the observable.

So in your case you could do

let something = lastValueFrom(
  this.http.get<resultDTO>('/api/account/test').pipe(
    timeout(5000)      // <-- HTTP request will error out if no response for 5 seconds
  ),
  { defaultValue: { data: ''} }  // <-- default value to be used
).then(res => {
  this.note = (res.data);
});

Being said that, this is one of those cases where I'd say there is no inherent need for converting the Observable to a Promise. You could simply make do only with the observable

this.http.get<resultDTO>('/api/account/test').pipe(
  timeout(5000)      // <-- HTTP request will error out if no response for 5 seconds
).subscribe({
  next: (res: resultDTO) => {
    this.note = res.data;
  },
  error: (error: any) => {
    // handle errors
  }
});