I am currently trying to access an API with an Angular 2 (via Ionic 2) app. Our laravel backend is set up in such a way that it expects an Accept header with the content-type of the request, and no Content-Type header. Not just an empty Content-Type header, but none at all.
So, I am setting up the requisite parameters in Http, omitting Content-Type in the Headers, and that's where the problem starts: Angular 2 apparently can't keep its hands off the Content-Type. If I give it an object as the body of the request, it sets the Content-Type to application/json. Which is still understandable. Then I stringify the Object, which causes Angular to set the Content-Type to text/plain. Attempts, via
headers = new Header({Accept: 'application/json', Content-Type: undefined});
or
headers.append("Content-Type", undefined);
or any other combination of any header I could imagine that contains an Accept of application/json and nothing else, even headers.set or headers.delete fails, Angular 2 keeps just doing its thing.
Setting Content-Type to undefined was suggested elsewhere, I have also tried to set it to an empty string, to application/json when passing in the stringified JSON, Angular just doesn't give a flying f... about what I want. Is there a way to turn this automatism off? Am I still doing something wrong (I am importing Headers, which, aka the lack thereof, was a problem elsewhere, so that should be out)?
Here comes the code:
import { Injectable, Inject } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { ConfsService } from '../confs/confs.service';
import { ApiRequestBody } from './api.request.body';
@Injectable()
export class ApiService {
constructor(public confs: ConfsService, private apiRequestBody: ApiRequestBody, private http: Http) {
post (method: string, data: any):Promise<any> {
const api = this.confs.get().api;
const url = api['server'] + "" + api[method];
let allParams = this.apiRequestBody.toJSON(data);
let body = JSON.stringify(allParams);
let headers = new Headers({
'Accept': 'application/json',
'Content-Type': undefined,
});
let options = new RequestOptions({ headers: headers });
let obj = this.http.post(url, body, options).toPromise();
return obj;
}
}
The ConfsService just gets a couple of configuration parameters, aka the api server URL, and ApiRequestBody gets a service that creates a standard set of parameters that the API needs to even look at the request, in addition to those that are passed in via the data parameter (which is then merged into the standard parameters in the toJSON method) - no rocket science. And I am doing a toPromise() because I find a promise in this particular case easier to handle.