Setting Default Headers in Angular
When building an Angular app, the chances are high that you’re going to need to set the same headers for most, if not all, of your service class’ API requests. In this post, I’m going to demonstrate how to set default headers both statically and dynamically. The examples below were done using Angular 4.0.0.
Setting Request Headers in a Service Class
For setting headers in a one-off request, we can just define headers as
RequestOptions
and pass them as a argument to the http
client’s function. Keep in
mind that you’ll need to import Headers
and RequestOptions
from @angular/http
into the service class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Injectable()
export class WidgetService {
updateWidget(widget: Widget): Observable<Widget> {
const headers = new Headers({
'Content-Type': 'application/vnd.api+json'
});
const options = new RequestOptions({
headers: headers
});
return this.http
.put(`widgets/${widget.id}`, widget, options)
.map((response: Response) => {
return response.json();
});
}
Having to do this for every request will get old real fast, not to metion leave you with
repetitive code. Let’s see how to set the Content-Type
header for all requests by default.
Setting Static Default Request Headers
To ensure that every request from the http
client is configured with the same headers, we
need to define a class to hold this configuration. Our class should be a subclass of
BaseRequestOptions
. Then, in the constructor
, we can set our headers.
1
2
3
4
5
6
7
@Injectable()
export class RequestOptionsService extends BaseRequestOptions {
constructor() {
super();
this.headers.set('Content-Type', 'application/vnd.api+json');
}
}
In the app.module
we can tell Angular to use our custom class instead of
the default RequestOptions
.
1
2
3
providers: [
{ provide: RequestOptions, useClass: RequestOptionsService }
]
Setting the headers in this way means that the default headers are set when the Angular application starts up. In many cases this is just fine, but what if you need to set headers dynamically? Let’s take a look at how that can be done.
Setting Dynamic Default Request Headers
Let’s consider the following use case. Our app needs to authenticate user requests using an
access token. The user authenticates with their email and password and the API responds with
a JWT which our app stores in the browser’s localStorage
. Each subsequent request must have
the JWT in the Authorization
header. The problem is that before we have added the JWT to
localStorage
, the headers have already been set. Our Authorization
header might look like
this: "Authorization": "Beaer "
- missing the JWT. Another use case might involve setting a timestamp.
The solution is to override the merge
function. Every request merges options so we can define
our dynamic headers there.
1
2
3
4
5
6
7
8
9
10
11
12
13
@Injectable()
export class RequestOptionsService extends BaseRequestOptions {
constructor() {
super();
this.headers.set('Content-Type', 'application/vnd.api+json');
}
merge(options?: RequestOptionsArgs): RequestOptions {
const newOptions = super.merge(options);
newOptions.headers.set('Authorization',
`Beaer ${localStorage.getItem('app-token')}`);
return newOptions;
}
}