I have exact same requirement as mentioned in Add queueing to angulars $http service but need implementation in Angular 4.3 or 5 using the HttpInterceptor
from
I have the exact same requirement as you. The other answers work perfectly fine, just that it requires developer to create requests with another a custom service instead of native HttpClient
. You could try the following interceptor to apply queuing as well.
This solution requires you to add 2 services, a HttpInterceptor
and a service (RequestQueueService
) to manage the queue.
HttpInterceptor:
@Injectable()
export class QueueInterceptorService implements HttpInterceptor {
constructor(private queueService: RequestQueueService) { }
intercept(request: HttpRequest, next: HttpHandler): Observable> {
return this.queueService.intercept(request, next);
}
}
RequestQueueService:
@Injectable({
providedIn: 'root'
})
export class RequestQueueService {
private queue: ReplaySubject[] = [];
intercept(request: HttpRequest, next: HttpHandler): Observable> {
const requestQueueItem$ = new ReplaySubject();
const result$ = requestQueueItem$.pipe(
switchMap(() => next.handle(request).pipe(
tap(req => {
if (req.type == HttpEventType.Response) {
this.processNextRequest();
}
}),
catchError(err => {
this.processNextRequest();
throw err;
})
))
);
this.queue.push(requestQueueItem$);
if (this.queue.length <= 1) {
this.dispatchRequest();
}
return result$;
}
private processNextRequest(): void {
if (this.queue && this.queue.length > 0) {
this.queue.shift();
}
this.dispatchRequest();
}
private dispatchRequest(): void {
if (this.queue.length > 0) {
const nextSub$ = this.queue[0];
nextSub$.next();
nextSub$.complete();
}
}
}
Lastly, in AppModule:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
RequestQueueService,
{ provide: HTTP_INTERCEPTORS, useClass: QueueInterceptorService, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
BTW, I am using Angular 8 with rxjs 6.4.