256

Here is my code:

import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';

logIn(username: string, password: string) {
    const url = 'http://server.com/index.php';
    const body = JSON.stringify({username: username,
                                 password: password});
    const headers = new HttpHeaders();
    headers.set('Content-Type', 'application/json; charset=utf-8');
    this.http.post(url, body, {headers: headers}).subscribe(
        (data) => {
            console.log(data);
        },
        (err: HttpErrorResponse) => {
            if (err.error instanceof Error) {
                console.log('Client-side error occured.');
            } else {
                console.log('Server-side error occured.');
            }
        }
    );
}

and here the network debug:

Request Method:POST
Status Code:200 OK
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:46
Content-Type:text/plain

and Data are stored in 'Request Payload' but in my server doesn't received the POST values:

print_r($_POST);
Array
(
)

I believe the error comes from the header not set during the POST, what did I do wrong?

1
  • Yes, thanks! But after not receiving data on my Back-end, I went to application/x-www-form-urlencoded. Anyway the main question is anserwerd Commented Jul 31, 2017 at 10:59

10 Answers 10

432

The instances of the new HttpHeader class are immutable objects. Invoking class methods will return a new instance as result. So basically, you need to do the following:

let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json; charset=utf-8');

or

const headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8'});

Update: adding multiple headers

let headers = new HttpHeaders();
headers = headers.set('h1', 'v1').set('h2','v2');

or

const headers = new HttpHeaders({'h1':'v1','h2':'v2'});

Update: accept object map for HttpClient headers & params

Since 5.0.0-beta.6 is now possible to skip the creation of a HttpHeaders object an directly pass an object map as argument. So now its possible to do the following:

http.get('someurl',{
   headers: {'header1':'value1','header2':'value2'}
});
Sign up to request clarification or add additional context in comments.

17 Comments

Interesting. So, for us coming from OO world, set method name is somewhat misleading.
What if I want to set multiple headers? I've tried to chain the comment HttpHeaders().set(..).set(..) but now again the headers are not getting written to the HTTP header fields?!
It should work fine according to the src github.com/angular/angular/blob/master/packages/common/http/src/… . I cant help you any further without more information about your issue (code)
Why have headers and requests been made immutable? angular.io/guide/http#immutability
|
34

To add multiples params or headers you can do the following:

constructor(private _http: HttpClient) {}

//....

const url = `${environment.APP_API}/api/request`;

let headers = new HttpHeaders().set('header1', hvalue1); // create header object
headers = headers.append('header2', hvalue2); // add a new header, creating a new object
headers = headers.append('header3', hvalue3); // add another header

let params = new HttpParams().set('param1', value1); // create params object
params = params.append('param2', value2); // add a new param, creating a new object
params = params.append('param3', value3); // add another param 

return this._http.get<any[]>(url, { headers: headers, params: params })

2 Comments

This method does not seem to work either. I mean, you can add the headers, and they will show in the lazyUpdate property, but eventually it will crash with the CreateListFromArrayLike exception when making the request effective by subscribing to it.
To add multiple headers use: headers:HttpHeaders = new HttpHeaders({ 'Application-Id': this.appId, "REST-API-Key": this.apiKey, "Content-Type": "application/json" });
16

set http headers like below in your http request

return this.http.get(url, { headers: new HttpHeaders({'Authorization': 'Bearer ' + token})
 });

Comments

10

I struggled with this for a long time. I am using Angular 6 and I found that

let headers = new HttpHeaders();
headers = headers.append('key', 'value');

did not work. But what did work was

let headers = new HttpHeaders().append('key', 'value');

did, which makes sense when you realize they are immutable. So having created a header you can't add to it. I haven't tried it, but I suspect

let headers = new HttpHeaders();
let headers1 = headers.append('key', 'value');

would work too.

2 Comments

Your first attempt should work, you're assigning the result of the append to the headers variable. Right now your explanation doesn't make any sense, specially your last guess that adding a let may fix it
both of them, for me, doesn't work
8

I was with Angular 8 and the only thing which worked for me was this:

  getCustomHeaders(): HttpHeaders {
    const headers = new HttpHeaders()
      .set('Content-Type', 'application/json')
      .set('Api-Key', 'xxx');
    return headers;
  }

Comments

5

In the manual (https://angular.io/guide/http) I read: The HttpHeaders class is immutable, so every set() returns a new instance and applies the changes.

The following code works for me with angular-4:

 return this.http.get(url, {headers: new HttpHeaders().set('UserEmail', email ) });

Comments

5

First, you need to add HttpHeaders with HttpClient

import { HttpClient,HttpHeaders  } from '@angular/common/http';

your constructor should be like this.

constructor(private http: HttpClient) { }

then you can use like this

   let header = new HttpHeaders({ "Authorization": "Bearer "+token});

   const requestOptions = {  headers: header};                                                                                                                                                                            

    return this.http.get<any>(url, requestOptions)
        .toPromise()
        .then(data=> {
            //...
            return data;
    });

1 Comment

how you get the token?
0

In my legacy app Array.from of prototype js was conflicting with angular's Array.from that was causing this problem. I resolved it by saving angular's Array.from version and reassigning it after prototype load.

Comments

0

I was struggling with this as well. I used an interceptor, it captures the response headers, then clone the headers(since headers are immutable objects) and then sends the modified headers. https://angular.io/guide/http#intercepting-requests-and-responses

Comments

-2

Angular 8 HttpClient Service example with Error Handling and Custom Header

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
    import { Student } from '../model/student';
    import { Observable, throwError } from 'rxjs';
    import { retry, catchError } from 'rxjs/operators';

    @Injectable({
      providedIn: 'root'
    })
    export class ApiService {

      // API path
      base_path = 'http://localhost:3000/students';

      constructor(private http: HttpClient) { }

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

      // Handle API errors
      handleError(error: HttpErrorResponse) {
        if (error.error instanceof ErrorEvent) {
          // A client-side or network error occurred. Handle it accordingly.
          console.error('An error occurred:', error.error.message);
        } else {
          // The backend returned an unsuccessful response code.
          // The response body may contain clues as to what went wrong,
          console.error(
            `Backend returned code ${error.status}, ` +
            `body was: ${error.error}`);
        }
        // return an observable with a user-facing error message
        return throwError(
          'Something bad happened; please try again later.');
      };


      // Create a new item
      createItem(item): Observable<Student> {
        return this.http
          .post<Student>(this.base_path, JSON.stringify(item), this.httpOptions)
          .pipe(
            retry(2),
            catchError(this.handleError)
          )
      }

      ....
      ....

enter image description here

Check complete example tutorial here

3 Comments

Is it me or is this kinda overkill for the question asked?
This isn't attempting to answer OPs question. Its just a bunch of code with no explanation whatsoever.
This is not even close to context. It looks like self-promotion.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.