Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty array becomes an array with a empty string element #494

Open
aazman opened this issue Sep 5, 2016 · 19 comments
Open

Empty array becomes an array with a empty string element #494

aazman opened this issue Sep 5, 2016 · 19 comments

Comments

@aazman
Copy link

aazman commented Sep 5, 2016

With httparty 0.14.0 if I I make a POST call like this HTTParty.post 'http://localhost:3000/somepath', body: {my_param: []} then at the other end I receive my_param with value [""] while with version 13.0.3 it still remains an empty array. Is this intended behavior in 0.14.0 or is this a bug?

@dotcom900825
Copy link

We also ran into this issue recently, and seems like in this commit: 7af4154, they allow to use emtpy array as the params, if you provide { people: [] } as part of the request body, then in the url it will become people[]=& which Rails will parse it and consider the params as people: [""]

@jnunemaker
Copy link
Owner

@dotcom900825 thanks for pointing that out. I'll close this since it seems to be fixed. Let me know if I'm misunderstanding.

@richkniles
Copy link

@jnunemaker Not understanding your comment. This issue isn't closed and the issue still exists in the latest version. Am I missing something?

@jnunemaker
Copy link
Owner

@richkniles ha. Sorry. I guess I am confused too. I thought @dotcom900825 was saying it was fixed, but maybe I read that wrong?

@qsona
Copy link

qsona commented Jan 5, 2017

@jnunemaker
We really can't represent an empty array on query params or form content-type body (such as x-www-form-urlencoded), but people[]= query param is more likely to be parsed as { 'people' => [""] }. Actually rails server parses as that. That is the current behavior of httparty, but it seems to be a bug. { people: [] } should be empty when it is converted to query param or form type body.

@ladelfa
Copy link

ladelfa commented Jun 16, 2017

This just bit us too, and took a while to track down.

When params[:object][:nested_objects_attributes] comes in as [""], rather than [ ] as it did in previous versions of httparty, it seems to break activerecord (3.2.22.5) lib/active_record/nested_attributes.rb:421:in `assign_nested_attributes_for_collection_association' -- we get TypeError: no implicit conversion of Symbol into Integer.

As a workaround, we'll just do something like

params[:object].each{|nested_k, nested_v| params[:object][nested_k] = [] if nested_v == [""] }

but this was a significant and unexpected behavior change.

@jnunemaker
Copy link
Owner

I'm 100% open to a PR with a test for this. I don't need/use this, so I am not sure off hand what people are wanting for a fix. If someone would take a stab at it, that would help.

@lakjain
Copy link

lakjain commented Oct 4, 2018

Hi, I am also facing this issue when upgrading the Ember. The queryparam when assigned as an empty array becomes an array with an empty string. Is there any solution to this ?

@DanCov
Copy link

DanCov commented Nov 8, 2018

This issue is still present in v0.16.2.

@TheSmartnik
Copy link
Collaborator

I've tested this in other http clients and none of them allow empty arrays. Neither for get, nor for post. rest-client converts it to nil, others just skip it altogether.

I feel like we need to revert changes from #477, because it introduces ambiguity. Now, there no way to distinguish between my_param: [] and my_param: [""]. As I don't like an idea of dropping keys with empty arrays entirely, restclient's approach seems like a good middle ground.


As for the workarounds, there are couple possibilities here:

  • if you need empty arrays, maybe use json content-type
  • if you don't need them you can use #to_query from ActiveSupport(unfortunately, URI.encode_www_form doesn't work with array very well)

@tescher
Copy link

tescher commented Jan 19, 2020

Just ran into this today. Did this get fixed? Still listed as open

@tescher
Copy link

tescher commented Jan 20, 2020

Not sure how kosher this is, but here's how I got around it:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  include SessionsHelper

  before_action :fix_params

  private

  # to get around the httparty bug that turns [] into [""] on http calls.
  def fix_params
    params.transform_values! { |v| v.kind_of?(Array) && v.count == 1 && (v[0] == "") ? [] : v }
  end
end

@jasondborneman
Copy link

jasondborneman commented Jul 29, 2020

Is this still an issue? I'm using 0.17.3 and encountering this problem. is it fixed AFTER 0.17.3 and should we upgrade?

I guess the open question for me is how do you even send an empty array to a REST endpoint now with HTTParty? Are we saying that that isn't supported/shouldn't be supported?

@TheSmartnik
Copy link
Collaborator

Is this still an issue?

Yes

@jasondborneman
Copy link

Is this still an issue?

Yes

Thanks for the quick response, @TheSmartnik. Any idea what the path forward is on this? It's wreaking havoc with our app trying to upgrade from a frankly very old version of httparty (0.13.7) to something closer to new. We've got two apps basically, a web app in rails and a ruby/cucumber framework that uses it for test metadata

I'm trying to convert the body from a hash to json with .to_json and explicitly setting teh content type to application/json but unfortunately that doesn't seem to be working for us.

Previously, when we just sent a hash as the body (hash.with_indifferent_access to be precise) by the time it got to our web app a nil parameter gets converted to an empty string. But when I do explicit .to_json on the body when sending it with HTTParty, it's NOT getting converted to an empty string (and our app fails now because it expects it to be a string). We'd also (the problem in this issue) send an empty array for a different param and it would show up in our web app as an empty array (not the [""])

So basically out of the frying pan and into the fire, unfortunately. To fix the latter problem (this issue) we now uncovered a new problem that nils aren't being converted to "" when we explicitly send json rather than the hash.

Hope that made a modicum of sense.

@TheSmartnik
Copy link
Collaborator

@jasondborneman

Any idea what the path forward is on this?
To be honest, I forgot about this issue. Will add a deprecation warning in the nearest days

Previously, when we just sent a hash as the body (hash.with_indifferent_access to be precise) by the time it got to our web app a nil parameter gets converted to an empty string. But when I do explicit .to_json on the body when sending it with HTTParty, it's NOT getting converted to an empty string (and our app fails now because it expects it to be a string). We'd also (the problem in this issue) send an empty array for a different param and it would show up in our web app as an empty array (not the [""])

Oh, I see. That's unfortunate. If I understand you correctly, sending JSON isn't required, is it?
If so you could try something like the following hack

HTTParty.post url, body: params.map { |key, value| value.to_query(key) }.join("&").gsub("%5B%5D=&", "%5B%5D&")

Should be parsed correctly by rails servers

@jasondborneman
Copy link

@TheSmartnik
Turns out I worked out the issues with sending it as json by setting the Content-Type header to application/json and then doing this to the body:
hash_body.comapct.to_json

This gets rid of nil stuff we don't need to pass and then converts to json.

So far that's working for us. Mileage may vary. If we end up finding out it's not working in call cases, I'll try your suggestion.

Thanks!

@gap777
Copy link

gap777 commented Aug 30, 2023

Is this still something plaguing you? We think we're seeing something like it in a Rails 7 server.

@thewoolleyman
Copy link

This is essentially the same issue as rails/rails#30740

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests