Search code examples
ruby-on-railsarraysjsonhttparty

HTTParty parsing sub-component of response


the following controller action

@result = HTTParty.post(
  'https://test.co.uk/interface/search', 
  :body => [...]

has a response. The response is not being viewed in expected json parsed structure. It is a long hash...

{"versionNumber"=>"5.5", "availabilitySummary"=>{"totalAvailable"=>102, "totalOnRequest"=>0}, 
"structures"=>[... big array]

The array has a number of sub-hashes "currencyCode"=>"USD", "info", "options"=>[sub-array]. I would like to access the array of stractures first in the view form (for testing purposes, before eventually commiting results to database.)

How can this be accomplished?


Solution

  • First of all, if possible, move the HTTParty stuff to a worker. This way, you will avoid your app crashing if the server you are hiting for the data is unavailable. Otherwise, make sure to wrap the HTTParty stuff in a begin - rescue - end block and catch appropriate exceptions there. Second of all, passing the entire JSON to a view and accessing it in the view is a bad practice because it drastically slows down template rendering. Instead, create a service object that would return the data model that's easy to access in a view. Give it a name that somehow describes what it relates to - MyJsonParser is probably not the best name, but you know what I mean. Implement a #call method which returns the data for you in a format that's easy to access in the view.

    my_json_parser.rb

    class MyJsonPArser
      def call
        response = post_request
        parse_structures(response)
      end
    
      private
    
      def post_request
        HTTParty.post(...)
      end
    
      def parse_structures(response)
        structures = response["structures"]
        # do more work with the big structures array ...
      end
    
    end
    

    your_controller.rb

    def your_method
      @data = MyJsonParser.new.call
    end
    

    your_view.html.erb

    <% @data.each do |item| %>
      <div><%= item %></div>
      ...
    <% end %>