Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injected Service in HttpInterceptor not initialized

I am trying to inject a service into an HttpInterceptor, here is the simple service

import { Injectable } from '@angular/core';
@Injectable()
export class LoginLoadingService {
   constructor() { }
   public loaded: boolean;
   isLoaded() {
       if (this.loaded === undefined) {
             this.loaded = true;
       }
       return this.loaded;
  }    
}

And the interceptor

import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from 
'@angular/common/http';
import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { LoginLoadingService } from './loading.service';
import 'rxjs/add/operator/do';
@Injectable()
export class LoginLoadingInterceptor implements HttpInterceptor {
  constructor(public loginLoadingService: LoginLoadingService) { }
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.loginLoadingService.loaded = false
    return next.handle(req).do((event: HttpEvent<any>) => {
      this.loginLoadingService.loaded = true;
    }, error => console.error(error));
  }
}

And in my app.module

providers: [
  LoginLoadingService,
  {
    provide: HTTP_INTERCEPTORS,
    useClass: LoginLoadingInterceptor,
    multi: true
  }
]

The HttpInterceptor is firing fine, but the loginLoadingService is not defined in the intercept() method. I tried to add deps to the interceptor in app.module, but that gave me this error

params.map is not a function

Not sure what the issue is here

like image 415
Isaac Levin Avatar asked Mar 12 '18 15:03

Isaac Levin


2 Answers

Define dependencies for interceptors like below:

for example, we have AuthInterceptor and we have injected LocalStorageService and SessionStorageService.

in app.module.ts we add interceptor AuthInterceptor :

   {
        provide: HTTP_INTERCEPTORS,
        useClass: AuthInterceptor,
        multi: true,
        deps: [LocalStorageService, SessionStorageService]
    },

This will work.

like image 162
Hadi Rasouli Avatar answered Oct 20 '22 22:10

Hadi Rasouli


The answer provided by @Hadi is the correct one.Thought I will add to this. The reason behind using deps in app module is explained in details in this article. https://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html#new-staticinjector-apis

Newer versions of Angular make use of StaticInjector where the DI framework of angular comes into play. We basically ask the Angular to provide us the singleton instance of a service when required by just injecting them as providers in app.module.

This is nothing but a shorthand version of {provide: token_name, useClass:class_name}

So we are requesting angular to inject a token of type (class) using the above code. Now if we need the token to be injected with existing service dependencies then we ask the token to be injected like this

{provide: token_name, useClass:class_name, deps: [deps_name]}

And that is why,the below resolves to the static injection of the interceptor

{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true, deps: [LocalStorageService, SessionStorageService] },

like image 6
vijayakumarpsg587 Avatar answered Oct 20 '22 23:10

vijayakumarpsg587