I'm new to Angular and I've just built an interceptor. According to multiple tutorials you have to include the HTTP_INTERCEPTORS
in the app.module
like so:
providers: [{ provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true }]
I was wondering what that multi: true
attribute means/does and whether it can be omitted or not.
I've read the angular.io guide about this attribute. They explain it as following:
I don't understand this part:
Note the multi: true option. This required setting tells Angular that HTTP_INTERCEPTORS is a token for a multiprovider that injects an array of values, rather than a single value.
This sheds some light on the concept but I don't really understand yet when an interceptor is injecting multiple values and when it isn't. For example, my own interceptor is only changing the headers. Does this mean its injecting only a single value?
This is my interceptor
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { LoginService } from '../Services/login.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private loginService:LoginService){}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
console.log("ik zit nu in de interceptor");
let currentUser = this.loginService.getToken();
if (currentUser !=="") {
request = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': `Bearer ${currentUser}`
})
});
}
return next.handle(request);
}
}
This is the provide list of app.module
providers: [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: 'AUTH_URL', useValue: 'http://localhost:8080/auth' },
{ provide: 'API_URL', useValue: 'http://localhost:8080/api' },
{ provide: 'HEADERS', useValue: new HttpHeaders({'Content-Type': 'application/json'}) },
LoginGuard,
LoginService,
UserService,
MessageService
],
From the description of the ValueProvider interface we can read for the multi
property:
When true,
injector
returns an array of instances. This is useful to allow multiple providers to spread across many files to provide configuration information to a common token.
This means that for the token we are providing a value, more than one value (or class) is going to be used.
For instance, see this example (this is a sample project) where it is specified for the token HTTP_INTERCEPTORS
to use the classes (useClass
) ErrorInterceptor
and SecurityInterceptor
. In order to get this working, we need to specify multi: true
so Angular knows that multiple values (or classes) are going to be used.
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: SecurityInterceptor,
multi: true
},
A key point here is that HTTP_INTERCEPTORS
is a multi-provider token. This means that when providing a new value or class for this token the property multi
is required and it must be set to true
.
See in the HttpClient documentation when it is described how to provide an interceptor the part where it is stated:
Note the
multi: true
option. This required setting tells Angular that HTTP_INTERCEPTORS is a token for a multiprovider that injects an array of values, rather than a single value.