Search code examples
ruby-on-railsjsonhttpruby-on-rails-5httparty

undefined method `each' for nil:NilClass when using API in Rails


This is obviously a common error. However, I am unable to resolve this issue when going over my code. I am trying to access ProPublica's API for congress. My model, view, and controller is pretty straightforward and this exact code has worked with me when accessing the Google News API.

I keep getting an undefined method error when I try and use the ".each" method in my view to iterate through the JSON response. I believe that I am passing the proper headers to the API as it requests.

My models:

class CongressTracker < ApplicationRecord
  include HTTParty

  def self.response
    #congress = "most recent congress"
    #chamber = "one each for congress and senate"
    #type = "introduced, passed, etc."

    congress_url = "https://api.propublica.org/congress/v1/115/senate/bills/passed.json"

    HTTParty.get(congress_url,
        :headers => {
        "X-API-KEY" => "api-key-here"
        })
  end
end


class Bill < ApplicationRecord
  include HTTParty
end

My controller:

class BillsController < ApplicationController
  def index
    @response = CongressTracker.response
  end
end 

My view:

<% @response["results"].each do |bill| %>
      <p><%= bill["title"]%></p>
      <p><%= bill["summary"]%></p>
  <% end %>

My route:

resources :bills

The error in detail:

  Rendering bills/index.html.erb within layouts/application
  Rendered bills/index.html.erb within layouts/application (2.0ms)
Completed 500 Internal Server Error in 312ms (ActiveRecord: 0.0ms)

ActionView::Template::Error (undefined method `each' for nil:NilClass):
    1: <% @response["results"].each do |bill| %>
    2:       <p><%= bill["title"]%></p>
    3:       <p><%= bill["summary"]%></p>
    4:   <% end %>

app/views/bills/index.html.erb:1:in `_app_views_bills_index_html_erb__2110131784793159686_70138696839360'

Example of expected JSON response (which I can get to work in the terminal):

{
   "status":"OK",
   "copyright":"Copyright (c) 2017 Pro Publica Inc. All Rights Reserved.",
   "results":[
      {
         "congress": "115",
         "chamber": "Senate",
         "num_results": "20",
         "offset": "0",
         "bills": [
              {
                 "bill_id": "hr2825-115",
                 "bill_type": "hr",
                 "number": "H.R.2825",
                 "bill_uri": "https://api.propublica.org/congress/v1/115/bills/hr2825.json",
                 "title": "DHS Authorization Act of 2017",
                 "summary": "",
              },

Solution

  • The reason you are getting the undefined method 'each' for nil:NilClass error, is most likely because the response is {"message"=>"Forbidden"}, because your API key is incorrect.

    I tested your code, and everything works correctly as long as you have the correct API key.

    You have some mistakes with your view, most likely because you don't have the results yet.

    To get the title and the summary of the bills you will need something like this:

    <% @response["results"].each do |result| %>
      <% result["bills"].each do |bill| %>
        <p><%= bill["title"]%></p>
        <p><%= bill["summary"]%></p>
      <% end %>
    <% end %>