NeyLive NeyLive - 1 month ago 8
JSON Question

Why do I get "undefined method 'fetch' for nil:NilClass (NoMethodError)"

I'm parsing JSON data to save to my db.

The JSON data is like this:

{"id"=>889066,
"email"=>"new.user@email.com",
"created_at"=>"2014-10-24T18:46:13Z",
"updated_at"=>"2014-10-24T18:46:13Z",
"status"=>"Registered",
"custom_status"=>nil,
"first_name"=>New,
"last_name"=>User,
"latest_visitor"=>
{"id"=>16998604, "tracking_code"=>"cab237f6-50ec-4424-9ea9-b0110070a6cb"},
"url"=>{"id"=>2422287, "url"=>"http://www.website.com/"},
"referrer"=>{"id"=>4234808, "url"=>"https://www.google.ba/"},
"affiliate"=>nil,
"campaign"=>nil,
"search_term"=>
{"id"=>344901, "term"=>"puppies", "search_engine"=>"google"},
"tracking_code"=>"cab237f6-50ec-4424-9ea9-b0110070a6cb"}]


For example I want to get the search engine value, so I do:

json = JSON.parse(response.body)
json.each do |item|
Model.create(
search_engine: item.fetch("search_term").fetch("search_engine")
)
end


This returns the error:

in 'block in <top (required)>': undefined method 'fetch' for nil:NilClass (NoMethodError)


EDIT: Here is the output of
puts item.keys
:

id
email
created_at
updated_at
status
custom_status
first_name
last_name
latest_visitor
url
referrer
affiliate
campaign
search_term
tracking_code


What am I doing wrong?

Answer

What you want to do is detect when the search_term is nil and do something about it.

If you want to discard it, that's easy

json = JSON.parse(response.body)
json.each do |item|
  search_term = item.fetch("search_term")
  next if search_term.nil?
  Model.create(
    search_engine: search_term.fetch("search_engine")
    )
end

If you want to provide some default search_engine value when there are no search_term:

DEFAULT_SEARCH_ENGINE = "N/A"
json = JSON.parse(response.body)
json.each do |item|
  search_term = item.fetch("search_term")
  if search_term.nil?
    search_engine = DEFAULT_SEARCH_ENGINE
  else
    search_engine = search_term.fetch("search_engine")
  end
  Model.create(
    search_engine: search_engine
    )
end
Comments