/ open source

Angular httpClient POST Duplicate Parameters Array (like php form elements) []

We were creating an Angular app which needed to post to a legacy PHP application and need to post same name / duplicate array parameters over a post request.

Our Angular app needed to send the following http post data:

data[] = value1
data[] = value2

Note the arguments are the same name, and we're not able/allowed to modify the existing system.
The browser encodes the above as:

data%5B%5D=value1&params%5B%5D=value2

After much searching:

Many articles assume your entpoint accepts JSON, but legacy applicications likley to not so you have to send the data in the format it exepcts.

  • angular http post array value
  • httpParamSerializer (not needed)
  • angular http square bracket param names php pos
  • angular http post same name parameters
  • angular http post multi values same

We came to the following solution from reading the Angular source for params it's simply a matter of using the append method of HttpParams which allows you to add to the the post data body rather than use HttpParams.set(), which will overwrite same-names parameters.

Use HttpParams.append() instead of HttpParams.set() when posting same-named post parameters in Angular.

An example service which performs Angular post request using HttpClient and HttpParams witl multiple same names parameters is below:

mypost.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Login } from './login';
import { Observable } from 'rxjs/Observable';
import { Router }  from '@angular/router';

@Injectable()
export class LoginService {

    private loginUrl = 'http://example.com/login';

    constructor(private http: HttpClient, private router: Router) { }

    login (login: Login): Observable<Object> {
        const headers = new HttpHeaders({
            'Content-Type': 'application/x-www-form-urlencoded',
            'Accept':'application/json, text/javascript, */*; q=0.01'
        });

        const body = new HttpParams()
            .set('params[]', login.username)
            .append('params[]', login.password);

        return this.http.post(this.loginUrl, body, {headers: headers});
    }
}