17

Angular 5.0.1

I'm looking at the docs for Angular HttpClient: https://angular.io/guide/http, but I can't seem to figure how to send POST params as a URLEncoded string instead of a JSON string. For instance, my Java http clients will send like this as default:

username=test%40test.com&password=Password1&rolename=Admin

But Angular wants to send as Json by default:

{"username":"test@test.com","password":"Password1","rolename":"Admin"}

Here's my code currently:

    let body = {
      username: "test@test.com",
      password: "Password1",
      rolename: "Admin"
    };

 let headers = new HttpHeaders();
    headers = headers.set("Content-Type", "application/x-www-form-urlencoded");


    this.http.post(this.baseUrl, body, {
      headers: headers,
    })
      .subscribe(resp => {
      console.log("response %o, ", resp);
    });

I've also tried adding HttpParams:

let  httpParams = new HttpParams();
httpParams.append("username", "test@test.com");
httpParams.append("password", "Password1");
httpParams.append("rolename", "Admin");

...
headers: headers,
      params: httpParams

But HttpParams seem to have no effect.

Any idea how to URL encode the request instead of Json?

jwBurnside
  • 849
  • 4
  • 31
  • 66
  • Possible duplicate of [HttpClient POST request using x-www-form-urlencoded](https://stackoverflow.com/questions/46714480/httpclient-post-request-using-x-www-form-urlencoded) – superjos Feb 16 '18 at 17:08

3 Answers3

16

append() returns a new HttpParams object, so you'll need to make a slight modification to your httpParams code. Try this:

let httpParams = new HttpParams()
    .append("username", "test@test.com")
    .append("password", "Password1")
    .append("rolename", "Admin");

In the code above, we chain our append calls, creating a new HttpParams object on each call. The last time we call append, the HttpParams object returned will contain all of the previously appended parameters.

Christian Santos
  • 5,386
  • 1
  • 18
  • 24
  • Ah yes, good catch that looks like it was the issue. As a note, looks like content type header is unnecessary as well. – jwBurnside Nov 22 '17 at 23:20
  • 1
    This doesn't work anymore. httpParams is still empty after this :( – Deniss M. Apr 06 '18 at 07:23
  • Seems great. But how we can add the whole object as a bulk operation and why should we add the parameters one by one?! Any answer idea is appreciated as I have lost a couple of hours trying to figure out how can I send a simple JS object from Angular 5. – Anton Mitsev Jul 19 '18 at 14:36
1

That is because HttpParam is immutable.

You can read why here

In short:

let httpParams = new HttpParams()
    .append("username", "test@test.com")
    .append("password", "Password1")
    .append("rolename", "Admin");

Because the app may retry requests, the interceptor chain may process an individual request multiple times. If requests were mutable, a retried request would be different than the original request. Immutability ensures the interceptors see the same request for each try.

Ced
  • 15,847
  • 14
  • 87
  • 146
0

Supply the HttpParams object as the body argument for post(). That way, you will send form data as the request body instead of JSON. Also, the params option is not needed.

Here's an example:

const body = new HttpParams()
  .set('username', 'test@test.com')
  .set('password', 'Password1')
  .set('rolename', 'Admin');

this.httpClient.post(url, body, {
  headers: new HttpHeaders()
    .set('Content-Type', 'application/x-www-form-urlencoded')
});

The HttpParams class is immutable. All mutation operations will return a new instance. You'll need to chain the set() calls to preserve the previously added parameters. You can use both set() and append().

Srdjan Pazin
  • 103
  • 2
  • 5