httparty icon indicating copy to clipboard operation
httparty copied to clipboard

Empty array becomes an array with a empty string element

Open aazman opened this issue 8 years ago • 19 comments

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?

aazman avatar Sep 05 '16 14:09 aazman

We also ran into this issue recently, and seems like in this commit: https://github.com/jnunemaker/httparty/commit/7af4154f0bcb82e80a3a54150a888806d08ec0d3, 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: [""]

dotcom900825 avatar Sep 22 '16 22:09 dotcom900825

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

jnunemaker avatar Sep 28 '16 13:09 jnunemaker

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

richkniles avatar Nov 16 '16 18:11 richkniles

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

jnunemaker avatar Nov 19 '16 02:11 jnunemaker

@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.

qsona avatar Jan 05 '17 17:01 qsona

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.

ladelfa avatar Jun 16 '17 15:06 ladelfa

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.

jnunemaker avatar Jun 27 '17 13:06 jnunemaker

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 ?

lakjain avatar Oct 04 '18 09:10 lakjain

This issue is still present in v0.16.2.

DanCov avatar Nov 08 '18 13:11 DanCov

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 https://github.com/jnunemaker/httparty/pull/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)

TheSmartnik avatar Nov 10 '18 14:11 TheSmartnik

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

tescher avatar Jan 19 '20 19:01 tescher

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

tescher avatar Jan 20 '20 05:01 tescher

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?

jasondborneman avatar Jul 29 '20 14:07 jasondborneman

Is this still an issue?

Yes

TheSmartnik avatar Jul 29 '20 15:07 TheSmartnik

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.

jasondborneman avatar Jul 29 '20 15:07 jasondborneman

@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

TheSmartnik avatar Jul 29 '20 17:07 TheSmartnik

@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!

jasondborneman avatar Jul 29 '20 18:07 jasondborneman

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

gap777 avatar Aug 30 '23 19:08 gap777

This is essentially the same issue as https://github.com/rails/rails/issues/30740

thewoolleyman avatar Jun 17 '24 00:06 thewoolleyman