raouaoul
raouaoul

Reputation: 881

Angular http post request content type from 'text/plain' to 'application/json'

Im trying to get data from a service using POST request. But I cant change the headers (TS wont compile) or content type. I get this error in console:

status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'text/plain' not supported"

Below is my component code.

import { Component, OnInit } from '@angular/core';
import { Http, Headers, Response, URLSearchParams } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {

  searchValue: any = '';

  constructor(private http: HttpClient) { }

  getData() {

    this.http.post('MY URL',
    JSON.stringify({
      "q": "Achmea"
    }))
    .subscribe(
    data => {
      alert('ok');
      console.log(data);
    }
    )

NB: Used the code snippet because the formatting wouldnt let me post as pre.

Using latest angular 4 version. Also server should be correctly configured, accepting only json data. I tried the examples from Angular docs but none of them worked.

Anyone have any idea how to get it working?? Thanks in advance.

Upvotes: 17

Views: 87922

Answers (7)

willingdev
willingdev

Reputation: 9546

deleteWithDescription(questionFileId: number, description: string): Observable<any> {
    const headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
    return this.httpClient.post(this.baseUrl + '/DeleteWithDescription/' + questionFileId, JSON.stringify(description), { headers: headers });
}


addExams(examId: number, questionsToInsert: QuestionDTO[]) {
    return this.httpClient.post<number[]>(this.baseUrl + '/DeleteAndInsertExams/' + examId, questionsToInsert);
}

Upvotes: 0

Wai Yan Moung
Wai Yan Moung

Reputation: 269

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
}

This work in angular

Upvotes: 1

Jaron
Jaron

Reputation: 135

I had a similar issue and was able to work around it using an HttpInterceptor. The example below should look for any Http request that would have a content type of 'text/plain' and convert the type to 'application/json' as well as convert the body json. Any other content type should be left alone.

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class ContentTypeInterceptor implements HttpInterceptor {

  public constructor() {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const ct = req.detectContentTypeHeader();
    return ct != null && ct.startsWith('text/plain')
        ? next.handle(req.clone({
                setHeaders: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(req.body)
            }))
        : next.handle(req);
  }
}

BTW, in my actual implementation, I used a whitelist (i.e. api) so I'm not accidentally modifying a request I did not intend to!

Upvotes: 1

HSG
HSG

Reputation: 334

I got it working with the httpClient and the code below:

const postUrl = this.config.baseUrl + '/Save/' + username;
    const headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    return this.http.post<string>(postUrl, '', {headers: headers});

Upvotes: 2

marco birchler
marco birchler

Reputation: 1746

In your example (and also in the comments) the two different http implementations which are provided by angular are mixed up. Since angular 4 HttpClient from '@angular/common/http' is available and is the recommended way to go. Since angular 5 the older Http from '@angular/http' is even marked as deprecated.

In order to prevent the exception message from your backend you have to set your headers in the following way:

const headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
return this.httpClient.post<T>(this.httpUtilService.prepareUrlForRequest(url), body, {headers: headers})
...

Please remove all dependencies from '@angular/http' in your code. As long as you are using objects from this modul you will have issues with your code.

Upvotes: 22

VithuBati
VithuBati

Reputation: 1928

As a best approach you can create a file called http-config.ts and insert below code

import {Headers} from '@angular/http';

export const contentHeaders = new Headers();
contentHeaders.append('Accept', 'application/json');
contentHeaders.append('Content-Type', 'application/json');

then in your service class

import {Http, RequestOptions, Headers, Response} from "@angular/http";
@Injectable()
export class MyService {
 url:string = '<paste your url here>'
 getData(id: string): Observable<any> {
   let options = new RequestOptions({headers: contentHeaders});
   return this.http
    .get(this.url, options)
    .map(this.extractData)
    .catch(this.handleError);}
 }

in your component

   constructor(private myService: MyService){}

   private subscription: Subscription;
   getData(popId: string) {
   this.subscription = this.myService.getData()
   .subscribe(
    (data: any) => {
      console.log(data);
    },
    error => {
      console.log(error);
    });
  }

hope that helps.

Upvotes: 2

Vincent Floriot
Vincent Floriot

Reputation: 89

Use headers :

var headers = new Headers({
    "Content-Type": "application/json",
    "Accept": "application/json"
});

this.http.post(this.oauthUrl, JSON.stringify(postData), {
    headers: headers
})

Upvotes: 4

Related Questions