angular: HttpParams doesn't accept array

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior


 let payload = new HttpParams();
payload.set('ids', [1,2,3,4]);

This is not accepted and compiled by ts because set method accepts just string.

Expected behavior

To be able to set array, and the serializer to make like this ids[]=1&ids[]=2&ids=[]3&ids[]=4

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: X.Y.Z


Browser:
- [x] Chrome (desktop) version XX
- [x] Chrome (Android) version XX
- [x] Chrome (iOS) version XX
- [x] Firefox version XX
- [x] Safari (desktop) version XX
- [x] Safari (iOS) version XX
- [x] IE version XX
- [x] Edge version XX
 
For Tooling issues:
- Node version: 6.9.12  
- Platform:  Mac 

Others:

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 33
  • Comments: 23 (2 by maintainers)

Commits related to this issue

Most upvoted comments

FYI, you can get to the expected behavior by using the .append method. For example:

const ids = [1,2,3];
let httpParams = new HttpParams();
ids.forEach(id => {
  httpParams = httpParams.append('id[]', id);
});
console.log(httpParams.toString()); // id%5B%5D=1&id%5B%5D=2&id%5B%5D=3

In case you are wondering, “%5B%5D” is just “[]” but url encoded.

I would still love to see this feature because it would give better support, but in the mean time hopefully this is helpful.

the promise of angular of being a full grown framework is just bs, the more I use it the more I hate it, know I have being forced to use 3rd party libs for basic things I supposed to have for granted, didn’t know multidimensional arrays in a ajax request was rocket science for ng team. With react out of the box I know I have to pick my own http library, just that the one delivered with ng sucks balls deep.

this core ticket is from sep 2017 and still open, ditching the ng boat, I had enough.

Trying to send a multidimensional array to an API but angular http.get doesn’t let me, this is total rubbish, time after time I get baffled how such simple things are so complicated or not possible at all with angular 2+, totally regretting not picking up something else like react.

/service?classId=68&services[classes/get-class][classId]=68&services[learner-access-rules/get-session][sessionId]=266&services[learner-access-rules/get-items][groupId]=27303&services[learner-access-rules/get-items][learnerAccessRuleId]=266&services[learner-access-rules/get-items][userId]=1290&services[learner-access-rules/get-items][filter][limit]=30&services[learner-access-rules/get-items][filter][page]=0&services[learner-access-rules/get-items][filter][sort]=activity_id&services[learner-access-rules/get-items][filter][order]=

@aldo-roman unfortunately no. The definition of the set method is: set(param: string, value: string): HttpParams; so value can be only a string. Also, I have checked the serializer and is not working as expected. I end up by makinh my own class

This worked for me.

let payload = new HttpParams();

[1,2,3,4,5].forEach((id:number) =>{
  payload = payload.append(`ids[]`, id.toString());
})

For anyone trying to do this, the simplest solution by far is just to use JSON.stringify():

let myArray = [12, 25, 37];
let params = new HttpParams();
params = params.append('myArray', JSON.stringify(myArray));

@chulian1819 How does react help? You can use any http library you want with angular, including those commonly used with react, e.g. axios… Use your own http library. Or better yet roll your own or write a helper function. The world is truly your oyster.

numeric value are easy, but what about the object value, for example, in primeng, the lazy load of datatable will pass the nested filter, for example

filters.fielda.value:b, 
filters.fielda.matchMode: null

and there is no easy way to convert this nested object to only name, and value.

so far I’m using {params: new HttpParams({fromString: jQuery.param(options)})}, for easy convert the datatable’s lazy parameter. this is the most easy way to handle the nested/complex params. but also, looks very stupid.

So, I have to say, the new HttpParams has a good design, but very bad in practise.

For anyone trying to use arrays here, here is how you do it:

new HttpParams({ fromObject: { paramName: arrayValue } })

The append-based workaround can be written more concisely using reduce:

const httpParams = ids.reduce((p, id) => p.append('id[]', id), new HttpParams());

I think this is a basic need for angular-user, but this issue is still open after almost 2 years.

the promise of angular of being a full grown framework is just bs, the more I use it the more I hate it, know I have being forced to use 3rd party libs for basic things I supposed to have for granted, didn’t know multidimensional arrays in a ajax request was rocket science for ng team. With react out of the box I know I have to pick my own http library, just that the one delivered with ng sucks balls deep.

this core ticket is from sep 2017 and still open, ditching the ng boat, I had enough.

welcome to workaraungular