Reputation: 2125
In my Angular2 application, I am setting header values to each and every request using CustomRequestOptions
class which extends BaseRequestOptions
.
@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
constructor(private _globals: Globals) {
super();
this.headers.set('Content-Type', 'application/json');
this.headers.set('X-Requested-By', 'Angular 2');
}
merge(options?: RequestOptionsArgs): RequestOptions {
// can I access the headers here I have set when the request is made ?
// and then conditionally set Content-Type
var newOptions = super.merge(options);
let hdr = this._globals.getAuthorization();
newOptions.headers.set("Authorization", hdr);
return newOptions;
}
}
As you can see, Content Type is set to application/json
.
Now I have a requirement to upload a photo to the server. The Content type has to be cleared for that request only.
The way I thought of using is setting some header value to the request, getting that value inside merge
method and conditionally clear the content type header.
Setting a custom header when the request is declared:-
let formData: FormData = new FormData();
formData.append('file', photoToSave);
let headers = new Headers();
//setting a custom header
headers.append('from', 'photo-upload');
let options = new RequestOptions();
options.headers = headers;
let savedPath = this._http
.post(this._endpointUrl + "save-photo", formData, options)
.map(
res => {
return res.json();
}
)
.catch(handleError);
Accessing the added header in merge method. This is where I have the problem. Can I do what I am trying to do. ? I tried following as a starting point. But the accessed headers are null. See the comment in the code.
merge(options?: RequestOptionsArgs): RequestOptions {
console.log("options header = " + options.headers); //this prints null
console.log("options body = " + options.body);
var newOptions = super.merge(options);
if(from header equal to 'photo-upload'){
newOptions.headers.set('Content-Type', '');
}else{
newOptions.headers.set('Content-Type', 'application/json');
}
let hdr = this._globals.getAuthorization();
newOptions.headers.set("Authorization", hdr);
return newOptions;
}
Now my question is about the validity of what I am trying to do. If it is not valid, please point me out a way to do this. Thank You..!
Upvotes: 0
Views: 3148
Reputation: 2125
I was able to resolve the issue by storing a variable from
in local storage of the browser instead of adding it as a header. This variable is assigned the name "photo-upload"
. (Whatever the name you prefer)
then, the next time the merge method is called, that from
variable is checked. If it contains the value "photo-upload"
, I just ignore. If it does not equal to "photo-upload"
I set the header value newOptions.headers.set('Content-Type', 'application/json');
if(localStorage.get("from") === "photo-upload"){
newOptions.headers.set('Content-Type', '');
}else{
newOptions.headers.set('Content-Type', 'application/json');
}
Upvotes: 0
Reputation: 2289
For this stuff, You can create one base service and inside that servce, You can set header for every API request.
BaseService file:
import { Injectable } from "@angular/core";
import { Http, RequestOptions, Headers } from "@angular/http";
@Injectable()
export class BaseService {
public apiUrl :string = 'your api url';
constructor(private http: Http) {
}
get(url: any) {
return this.http.get(this.apiUrl + url).do(data => {
console.log(data);
});
}
post(url: any, data: any) {
//Add uesr id every time for authentication
if (data != null) {
data.user_id = this.userId;
}
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
try {
return this.http.post(this.apiUrl + url, Json.serialize(data), options).do(data => {
if (data != null && data.statusText != "No Content") {
console.log("Response Data - ", data.json());
//data.statusText ="No Content","OK";
}
});
}
catch (e) {
console.log(e);
return null;
}
}
}
APIService file:
import { Injectable } from "@angular/core";
import { Response } from "@angular/http";
import { Observable } from 'rxjs/Observable';
@Injectable()
export class ApiService {
constructor(public http: BaseService) {
}
//Toolbar
public GetToolbarCollection(id: any): any {
let data = {
id: id
};
return this.http.post('GetToolbarCollection', data)
.map((response: Response) => {
return new ToolbarCollection(response.json());
})
.catch(this.handleError);
}
public SetToolbarCollection(toolbarCollection: ToolbarCollection): any {
let data = {
toolbarCollection: toolbarCollection
};
return this.http.post('Portal/SetToolbarCollection', data)
.map((response: Response) => {
return new ToolbarCollection(response.json());
})
.catch(this.handleError);
}
private handleError(error: Response) {
HideLoader();
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
In above code BaseService
has two methods including get and set. Inside this ApiService
I am using BaseService so every request will have custom header from base service.
Upvotes: 3