Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$http buildUri function not converting arrays properly #7363

Closed
mingos777 opened this issue May 6, 2014 · 16 comments
Closed

$http buildUri function not converting arrays properly #7363

mingos777 opened this issue May 6, 2014 · 16 comments

Comments

@mingos777
Copy link

I have a http GET request where I want to send an array:

$http({
    url: "/foo",
    method: "GET",
    params: {
        countries: [
            "US",
            "GB"
        ]
    }
});

I expect the built URL to be /foo?countries[]=US&countries[]=GB or, at the very least /foo?countries=["US","GB"] (this was the case of Angular.js 1.0.8).

However, the URL is actually /foo?countries=US&countries=GB - by all measures, this is an invalid query string.

The changes in $http's buildUrl function seem to have introduced the misbehaviour. It would be nice to see this fixed, as I need to do some really ugly patching to counter this.

@caitp
Copy link
Contributor

caitp commented May 6, 2014

by all measures, this is an invalid query string.

Can you find a line in the RFC which considers this an invalid query string?

@mingos777
Copy link
Author

Dear @caitp, while I value you as a knowledgeable contributor to the Angular.js community, I'm afraid your nitpick brings little to the issue I've raised. I need to send an array. Angular.js $http service deforms the data I pass to it, resulting in a query string that's useless to me, as after decoding by the PHP backend, it contains completely different data than what I intended to send. Compliance with an RFC is one thing, but deforming the data it's supposed to process correctly is another.

By the way, I just looked at the doc for $http. For the params property of the config argument, it says, and I quote:

Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.

The array in my example, which is not a string, is not JSONified. It worked fine in 1.0.8 though.

@caitp
Copy link
Contributor

caitp commented May 6, 2014

If you can write a reproducible test case which demonstrates that $http is doing something wrong, then please show it, but otherwise this looks like another "please do non-standard stuff like jQuery does!" request

@shahata
Copy link
Contributor

shahata commented May 6, 2014

@mingos777 - wouldn't passing:

$http({
    url: "/foo",
    method: "GET",
    params: {
        countries: angular.toJson([
            "US",
            "GB"
        ])
    }
});

or

$http({
    url: "/foo",
    method: "GET",
    params: {
        'countries[0]': "US",
        'countries[1]': "GB",
    }
});

solve your problem?

@mingos777
Copy link
Author

@caitp I'm not asking for non-standard features. This worked perfectly as described in the docs in 1.0.8. In 1.2.16, it does not. My example is code that can be used in your 100% reproducible test. Against 1.0.8, it does what it says on the box. In 1.2.16, it does not.

@shahata Yes, and that's what I will be using for the time being, until the issue is fixed in Angular.js. But the point isn't to use hackery to counter bugs in the software I use. The point it to help improve that software so that no hackery will be needed.

@caitp
Copy link
Contributor

caitp commented May 6, 2014

@mingos777 so create a reproducible test and host it somewhere, that would be fantastic. thanks.

@pkozlowski-opensource
Copy link
Member

@caitp I think we should encapsulate request params serializing into a service so people can swap it and have serailization that suits their backend needs. The current schema works for Java servlets, for example, but fails for PHP, afaik.

I was thinking of adding such a service several times already and can send a PR over the weekend. I think that there are number of other issues opened for this, ex.: #3740

@shahata
Copy link
Contributor

shahata commented May 6, 2014

@caitp - here's a reproduce for the issue - http://plnkr.co/edit/MzcOdgIgy8MnayFP8f3Q?p=preview

I'm interested though, what do you think should be the correct behavior here in your opinion? It sounds to me that probably each backend technology has it's own non-standard way of dealing with arrays, no? Or is there some more common pattern?

Maybe we should somehow let ppl customize this...

@pkozlowski-opensource
Copy link
Member

Maybe we should somehow let ppl customize this...

@shahata this is my take on this as well

@mingos777
Copy link
Author

@shahata Thank you for creating the test.
Here is the modified version using Angular.js 1.0.8 - in this case the array is actually JSONified.

@e-oz
Copy link

e-oz commented May 8, 2014

@pkozlowski-opensource , in response to your message: #7385 (comment)

there is RFC for this case:
http://www.ietf.org/rfc/rfc3986.txt

and it describes your "2" variant.

@e-oz
Copy link

e-oz commented May 8, 2014

also, my personal opinion, without RFC, 3 variant (JSONifying variable) is ugliest one (with all my love to JSON, it can't be "default" part of HTTP standard).

@pkozlowski-opensource
Copy link
Member

@Jamm interesting, I didn't know that the format of the query string is specified to this level of details in the mentioned rfc. I'm just reading through it and can't spot relevant section. Could you please help me identify the section in the rfc that defines (2) as the serialization schema?

@e-oz
Copy link

e-oz commented May 8, 2014

@pkozlowski-opensource I was wrong, there is no standard for that, sorry. I just found link to that standard in few manuals as basis of their choice how to encode request. I checked RFC 3986, 1738 and I can't find there any descriptions of that. Well, at least I hope it will not be JSON. Or we can't properly decode it on server-side (it's naive to think that all our request to backend will be encoded in JSON and try to decode them).

@FGRibreau
Copy link

What a coincidence I had the same issue as @mingos777 today (Play Framework 2.1 requires the [] format on get requests). I just sent a pull-request (without unit-tests) don't hesitate to tell me what I should add/fix to make it mergeable into master.

lgalfaso added a commit to lgalfaso/angular.js that referenced this issue May 10, 2014
Add the ability to add parameters serializers
Add common parameters serializers

Closes angular#7363
lgalfaso added a commit to lgalfaso/angular.js that referenced this issue May 10, 2014
Add the ability to add parameters serializers
Add common parameters serializers

Closes angular#7363
@lgalfaso
Copy link
Contributor

With the clarification at #7423 (comment) there are other ways to make this work that does not involve a change in the core. I am closing this

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
7 participants