Usually it's desirable to have default timeout (e.g. 30s) that will be applied to all requests and can be overridden for particular longer requests (e.g. 600s).
There's no good way to specify default timeout in Http
service, to my knowledge.
What is the way to approach this in HttpClient
service? How to define a default timeout for all outgoing requests, that can be overriden for specific ones?
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, where it can be decided if it's default or specific timeout that should be applied via RxJS timeout
operator:
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 = req.headers.get('timeout') || this.defaultTimeout;
const timeoutValueNumeric = Number(timeoutValue);
return next.handle(req).pipe(timeout(timeoutValueNumeric));
}
}
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 a custom timeout
header
http.get('/your/url/here', { headers: new HttpHeaders({ timeout: `${600000}` }) });
Since headers are supposed to be strings, the timeout value should be converted to a string first.
Here is a demo.
Credits go to @RahulSingh and @Jota.Toledo for suggesting the idea of using interceptors with timeout
.
The solution explains how to specify default timeout (30s) and override it for particular requests (600s). By default there is no timeout in HttpClient
. In case there's already one, this means the cause is different, most likely a webserver, which is not uncommon, e.g. Angular CLI devserver. This is a different problem that cannot be solved from client side, regardless of Angular or any other client-side framework.