0

I'm using HTTParty to make calls to an API. When I have callback in the url it causes MultiJson::DecodeError:

MultiJson::DecodeError in PagesController#home

756: unexpected token at '12345({"label":"daydata","data":[[1335484800883,69586],
[1335571201001,17725]]});

My get call looks like this:

@data = HTTParty.get("http://powermeters.appspot.com/getdays?id=1234567890&from=2012-04-24&to=2012-04-29&callback=12345")

Does anyone know what is causing this, and how to solve it?

Elijah Murray
  • 2,132
  • 5
  • 30
  • 43
Anders
  • 2,903
  • 7
  • 58
  • 114

2 Answers2

2

The problem is that the response is javascript, not JSON. To fix it you can do:

response.gsub! /^\d+\((.*)\);?$/m, '\\1'

or something similar.

pguardiario
  • 53,827
  • 19
  • 119
  • 159
  • Yep, looks like a JSONP service, where you specify a callback to execute on your own website, via a ` – d11wtq May 07 '12 at 12:39
  • @d11wtq Mm, ok. Is it possible to get the request in a Rails controller, I do some additional calculations on the data. Or do I have go get it from Javascript and then pass it to my controller, and how would a script like that look? Thanks. – Anders May 07 '12 at 12:56
  • Did you try @pguardiario's suggestion of just stripping away the function call that is wrapped around it? – d11wtq May 07 '12 at 14:44
  • @d11wtq Yes, I tried, but I didn't get it to work. The app seems to crash as soon as I make the get request with HTTparty so I don't know if I will have a response to gsub!. Do you know where I should put it? – Anders May 08 '12 at 10:49
  • I finally got it to work, by using @pguardiario's answer and by changing from HTTParty to Net:HTTP.get_response, as of: http://stackoverflow.com/questions/9917666/nesting-too-deep-error-while-retrieving-json-using-httparty. Thanks! – Anders May 08 '12 at 14:01
0

You can also override the parser. A simple example is below.

The if MultiJson... is pulled straight from HTTParty's json parser

class Foo
  include HTTParty
  base_uri "http://foo.bar"

  parser lambda { |body,_|
    new_body = body.gsub(/^\d+\((.*)\)$/, '\1')
    if MultiJson.respond_to?(:adapter)
      MultiJson.load(new_body)
    else
      MultiJson.decode(new_body)
    end
  }
end
Daniel Evans
  • 6,788
  • 1
  • 31
  • 39