Intercept HTTP Requests in Angular and Ionic 2
Angular has an impressive dependency injection system, however some aspects could be documented better. Old blog posts explaining how things worked before the final release don't help either. Hence, it took me a while to successfully intercept HTTP requests and inject a common parameter.
The HTTP requests can be intercepted by injecting your own implementation of BaseRequestOptions
class:
import { BaseRequestOptions, RequestOptionsArgs, RequestOptions, URLSearchParams } from '@angular/http';
export class AppRequestOptions extends BaseRequestOptions {
merge(options?: RequestOptionsArgs): RequestOptions {
let newOptions = super.merge(options);
// params is not instantiated if original request has no parameters
newOptions.params = newOptions.params || new URLSearchParams();
// params was introduced in Angular 4 / Ionic 3
// in Angular 2 / Ionic 2 use search instead
newOptions.params.set('api_key', '234jhf35brhf3f7fv3v78f39');
return newOptions;
}
}
In the above snippet I add an api_key
parameter to every request but I could also add headers or change other aspects of the request.
To actually inject this implementation, add the following entry to the providers
array of NgModule
declaration:
@NgModule({
// ...
providers: [
// ...
{provide: RequestOptions, useClass: AppRequestOptions}
]
})
You can inject other providers in your BaseRequestOptions
implementations as well:
export class Configuration {
apiKey = '234jhf35brhf3f7fv3v78f39';
}
@Injectable()
export class AppRequestOptions extends BaseRequestOptions {
constructor(private config: Configuration) {
super();
}
merge(options?: RequestOptionsArgs): RequestOptions {
let newOptions = super.merge(options);
newOptions.params = newOptions.params || new URLSearchParams();
newOptions.search.set('api_key', this.config.apiKey);
return newOptions;
}
}
For this to work, you need to add the Injectable
decorator to your class or you'll get the following not so helpful error:
Can't resolve all parameters for AppRequestOptions: (?)
Also don't forget to include Configuration
to NgModule
's providers
array:
@NgModule({
// ...
providers: [
// ...
{provide: RequestOptions, useClass: AppRequestOptions},
Configuration
]
})