Adding a HTTP header to the Angular HttpClient doesn't send the header, why?

AngularHttp HeadersAngular Httpclient

Angular Problem Overview


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?

Angular Solutions


Solution 1 - Angular

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

Solution 2 - Angular

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

Solution 3 - Angular

set http headers like below in your http request

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

Solution 4 - Angular

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.

Solution 5 - Angular

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

Solution 6 - Angular

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

Solution 7 - Angular

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

Solution 8 - Angular

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.

Solution 9 - Angular

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

Solution 10 - Angular

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFrennetixView Question on Stackoverflow
Solution 1 - AngularJota.ToledoView Answer on Stackoverflow
Solution 2 - AngularHallyson AlmeidaView Answer on Stackoverflow
Solution 3 - AngularrajamallareddysView Answer on Stackoverflow
Solution 4 - AngularMartin HortonView Answer on Stackoverflow
Solution 5 - AngularRaghavView Answer on Stackoverflow
Solution 6 - AngularRob LasscheView Answer on Stackoverflow
Solution 7 - AngularRamazan ZülkarneynView Answer on Stackoverflow
Solution 8 - AngularAvinash WableView Answer on Stackoverflow
Solution 9 - AngularchaimiteView Answer on Stackoverflow
Solution 10 - AngularCode SpyView Answer on Stackoverflow