17

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.

7 Answers 7

22

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.

Sign up to request clarification or add additional context in comments.

Comments

4

Use headers :

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

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

6 Comments

[ts] Argument of type '{ headers: Headers; }' is not assignable to parameter of type '{ headers?: HttpHeaders; observe?: "body"; params?: HttpParams; reportProgress?: boolean; respons...'. Types of property 'headers' are incompatible. Type 'Headers' is not assignable to type 'HttpHeaders'. Property 'headers' is missing in type 'Headers'. This is what my visual studio code says on the headers line and wont compile..
Check if you add this to your import : import { Http, Headers, Response, RequestOptions, ResponseContentType } from '@angular/http';
No this does also not work. I also had them imported too... Every answer I see on stackoverflow related to this breaks down on me on the headers part.
i see you used headers:Headers instead of the var headers.
I copied the code you put here, didnt change the header part, only the url.
|
2

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.

4 Comments

this is also not working. this part on service gets totally underlined in vsc. return this.http .get(this.url, options) .map(this.extractData) .catch(this.handleError); and also when this.myService on component page
actually, you have to inject your service into your component. I updated my answer. if you still get any error, kindly post it here
I got an error in vsc that didnt let the code to compile in that part in component: this.myService.getData() Im very new to angular and Im not sure even where to put my URL in that case. I would really just like a very simple way to get this working.
you can put the URL in the service itself. I updated the code. and also could you please paste the error you get in the comments
2

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});

Comments

1

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!

Comments

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

This work in angular

Comments

0
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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.