Marc
Marc

Reputation: 13184

Increase timeout in Angular 2+ and ASP.NET Core WebAPI application

In my Angular 2+ / ASP.NET Core MVC WebAPI application I have a long running API-call from the client UI to the server. The request times out after 30 seconds. I would like to define the timeout for this specific API call either client- or server-side.

I have only found ways to configure the server timeout globally, which is not what I want, as the 30 second timeout is fine for other calls. I've also found solutions to decrease the timeout client side by piping RxJS's timeout operator. However, as I understand, this is not suitable for increasing the timeout?

How can I set the timeout on this specific request? Where does the 30 second default come from?

(The code doesn't actually matter, as it is a standard API controller and a standard Angular HTTP call):

this.http.get('api/xyz').subscribe(d => { ... });

Upvotes: 2

Views: 2702

Answers (2)

Tachyon
Tachyon

Reputation: 2411

It appears that without extending HttpClientModule classes, the only expected ways for interceptors to communicate with respective requests are params and headers objects.

Since timeout value is scalar, it can be safely provided as a custom header to the interceptor.

import { Inject, Injectable, InjectionToken } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { timeout } from 'rxjs/operators';

export const DEFAULT_TIMEOUT = new InjectionToken<number>('defaultTimeout');

@Injectable()
export class TimeoutInterceptor implements HttpInterceptor {
  constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const timeoutValue = Number(req.headers.get('timeout')) || this.defaultTimeout;

    return next.handle(req).pipe(timeout(timeoutValue));
  }
}

This can be configured in your app module like:

...
providers: [
  [{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }],
  [{ provide: DEFAULT_TIMEOUT, useValue: 30000 }]
],  
...

The request is then done with custom timeout header

http.get(..., { headers: new HttpHeaders({ timeout: `${20000}` }) });

Upvotes: 1

TheParam
TheParam

Reputation: 10541

To solve the timeout issue you can use the timeout from RxJs like below

Pass time in milliseconds to timeout operator

Here I am passing 60 seconds as timeout, so after 60 seconds if there is no response from the server then it will throw timeout error.

import ‘rxjs/add/operator/timeout’; 

...

this.http.get('api/xyz').timeout(60000).subscribe(d => { ... });

Upvotes: 2

Related Questions