I am using Angular 4.3.1 and HttpClient. There is an HttpInterceptor to set some headers.
In some http get requests I need to set a different header. Is there anywa
Currently, Angular does not support passing "interceptor config/metadata" via the HttpRequest object (it has been an open issue for quite some time).
As a possible workaround, we can define a new MyHttpParams
class which extends Angular's HttpParams
, adding a new interceptorMetadata
property.
Note that MyHttpParams
must override the append
, set
and delete
methods so that they return MyHttpParams
instead of Angular's HttpParams
. If we don't do this, our interceptorMetadata
will be "dropped" when those methods are invoked (e.g. if an interceptor adds some HTTP param, the next interceptors will not get the interceptorMetadata
).
import {HttpParams} from '@angular/common/http';
export interface InterceptorMetadata {
readonly customParam1: string;
readonly customParam2: number;
// etc.
}
export interface MyHttpParamsConfig {
interceptorMetadata: Partial;
params: string | Record; // the actual params which will be included in the real request
}
export class MyHttpParams extends HttpParams {
public readonly interceptorMetadata: Partial;
constructor({params, interceptorMetadata}: Partial = {}) {
if(typeof params === 'string') {
super({fromString: params});
}
else if(typeof params === 'object') {
super({fromObject: params});
}
else {
super();
}
this.interceptorMetadata = interceptorMetadata;
}
// orverrides HttpParams.append
append(param: string, value: string): MyHttpParams {
const updatedHttpParams = super.append(param, value);
return new MyHttpParams({
interceptorMetadata: this.interceptorMetadata,
params: updatedHttpParams.toString()
});
}
// orverrides HttpParams.set
set(param: string, value: string): MyHttpParams {
const updatedHttpParams = super.set(param, value);
return new MyHttpParams({
interceptorMetadata: this.interceptorMetadata,
params: updatedHttpParams.toString()
});
}
// orverrides HttpParams.delete
delete(param: string, value?: string): MyHttpParams {
const updatedHttpParams = super.delete(param, value);
return new MyHttpParams({
interceptorMetadata: this.interceptorMetadata,
params: updatedHttpParams.toString()
});
}
}
Then for example when calling HttpClient.get() we can pass an instance of our extended MyHttpParams:
const myHttpParams = new MyHttpParams({
interceptorMetadata: {
customParam1: 'test', // this will NOT be part of the final request
},
params: 'someActualUrlQueryString=someValue' // this will be part of the final request
});
httpClient.get(myUrl, {params: myHttpParams})
Finally, in our interceptor we can use interceptorMetadata
:
intercept(req: HttpRequest, next: HttpHandler): Observable> {
const {params} = req;
if(params instanceof MyHttpParams) {
if (params.interceptorMetadata && params.interceptorMetadata.customParam1 === 'test') {
// do something
}
}
// ...
}
Thanks to JWess for the original answer which this is based on (it was just missing the append
, set
and delete
overrides)