How to catch an "undefined method `[]' for nil:NilClass" error? - ruby-on-rails

I get an nested array from facebook via omniauth and wanna check if it's empty?/nil?/exists?
the depending line looks like:
unless omniauth['extra']['raw_info']['location']['name'].nil?
This should check if this part of the array is empty or exists.
But always this error was thrown:
undefined method `[]' for nil:NilClass
Do I check arrays wrong?
I tried it with "has_key" "nil?" "empty?" "exists?" "blank?"
But no one of these works!
Please help me, many thanks in advance!

Ideally you should check each nested level to see if it is nil, however, this will also work.
unless (omniauth['extra']['raw_info']['location']['name'] rescue nil).nil?
You can also rescue the NoMethodError specifically.

This error is raised because one of the hash values in the chain of omniauth['extra']['raw_info']['location']['name'].nil? returns nil and it is not the last call ['name'].
If for example omniauth['extra']['raw_info'] returns nil, you're actually trying to call nil['location'] which raises an error in ruby.
You can catch this error simply:
res = omniauth['extra']['raw_info']['location']['name'].nil? rescue true
unless res
#your code here
end
Please notice that the code block above will fill the variable res with true if the ['name'] hash value is nil or any other hash value in the chain returns nil.

A bit late to the party, but, as pointed in this answer, Ruby 2.3.0 introduced a new method called dig, which would return nil if one of the chained keys is nil. Your omniauth auth hash could then be presented as:
omniauth = {
...
"extra"=>{ "raw_info"=>
{ "location"=>"New York",
"gravatar_id"=>"123456789"}}
...
}
omniauth.dig('extra',
'raw_info',
'location',
'name',
'foo',
'bar',
'baz') #<= nil

Related

Undefined method `to_date' for nil:NilClass

I tried to put a try method for fixing the error,but it won't still want it to work out.
If I wasn't specific enough, please let me know.
How to fix this error?
Generally speaking, if you see a message saying "Undefined method 'foo' for nil:NilClass" it means that you are calling the method "foo" on an object whose value is nil. Like everything in Ruby, "nil" is an object, and it's class is NilClass - that's what the message means.
In this case, the object in question is params[:date], since that is what you are calling the .to_date method on. params is a Hash (well, a hash-like object at least), and with a hash, if you call a key on it and it doesn't have that key, it returns nil.
So, your problem is that you are expecting params[:date] to have something in it, and it doesn't.
Maybe you should handle situations when the parameter :date hasn't been given. Maybe use a default value like this:
if params.has_key?(:date)
date = DateTime.parse(params[:date])
else
date = DateTime.now
end
po_id = CardApplicationTrack.where(
:batched_for_payment => true,
:admin_user_id => params[:admin_user_id].to_i,
:created_at =>
date.beginning_of_day ..
date.end_of_day
).map { |cat| cat.processing_order_id }
Or tell the user that you didn't enter a date if params[:date] is missing.
You can also use .try method, try following.
date = params[:date].try(:to_date) || DateTime.now
po_id = CardApplicationTrack.where(
batched_for_payment: true,
admin_user_id: params[:admin_user_id].to_i,
created_at: date.beginning_of_day..date.end_of_day
).pluck(:processing_order_id)
This will not throw error.
params[:date].try(:to_date).try(:end_of_day)

Ruby - NoMethodError (undefined method for nil:NilClass):

I'm having some difficulty trying to figure out what I am doing wrong. My ActiveRecord query is returning nil which I think is causing NoMethodError to be raised.
Here's what I have:
#number_exclude_list = ["1234567890", "2223334545"]
#available_number = UserNumber.where.not(:user_num => #number_exclude_list)
Which returns an empty set of rows:
=> #<ActiveRecord::Relation []>
So, then I have:
if (#available_number.empty?)
inform_user_empty
else
do_my_other_function
But, I get:
`NoMethodError (undefined method 'inform_user_empty' for nil:NilClass)`
I have tried: #available_number.blank? and `#available_number.nil?
And I still get the same NoMethodError. Any ideas on what I am doing wrong here?
The exception text NoMethodError (undefined method 'inform_user_empty' for nil:NilClass) says that is was a call to instance method #inform_user_empty of the nil class'es instance, and since nil has no instance method ruby interpreter throwed that exception. I see the two main reason for it:
self keyword variable has nil value, I believe not in the reason, because you do a call from a controller, as you've said ApplicationController. To make sure that self isn't nil, change the code to the following one:
if #available_number.empty?
p self
self.inform_user_empty
rerun the action, and look at the result.
The exception has been thrown from another place. So you have to specify the full trace log in your post.
Please run the below line in your console:
#available_number = UserNumber.where.not(:user_num => #number_exclude_list)
it returns an ArgumentError: wrong number of arguments (0 for 1+) since it is not the way to check NOT IN condition in Rails activerecord.
Replace it with:
User.where('user_num NOT IN (?)',#number_exclude_list)
and then do:
if #available_number == nil
inform_user_empty
else
do_my_other_function
end
Hoep that will resolve the issue. Please let me know if it really helped you.

Vaccum hash from xml throws Null pointer in code, but renders fine in json

I am using vaccum to fetch product details from Amazon Product Advertising API.
req = Vacuum.new
req.configure(key: configatron.api.amazon.productAPI.key,
secret: configatron.api.amazon.productAPI.secret,
tag: 'biz-val')
regex = Regexp.new "http://([^/]+)/([\\w-]+/)?(dp|gp/product|exec/obidos/asin)/(\\w+/)?(\\w{10})"
productID=regex.match(#url).captures[4];
host=regex.match(#url).captures[0];
utype=regex.match(#url).captures[2];
#url="http://#{host}/#{utype}/#{productID}"
params = { 'Operation' => 'ItemLookup',
'ItemId' => productID,
'ResponseGroup'=>'Large'
}
res = req.get(:query => params)
hsh=Hash.from_xml(res.body)
#details=hsh
item=hsh[:ItemLookupResponse][:Items][:Item]#Throws an Undefined method [] for nilClass
You can ignore the regex parsing. I have checked it works fine.The hash that is generated from res.body is a valid hash, it shows up fine in the json rendered(#details), but throws a nilClass thing when I try to access it in the code.
I think thi might be becausehsh[:ItemLookupResponse] returns something other than a hash. I am not sure what it is returning though. How do I access :Items ?
If it says you are trying to call [] on a NilClass then it is highly likely that you are. On that particular line you call [] on these three
hsh
hsh[:ItemLookupResponse]
hsh[:ItemLookupResponse][:Items]
So one of them is, again highly likely, to be nil. You might want to use debugger/repl and put a breakpoint right before the erring line and examine hsh. I use pry, with which you woud first require 'pry' and then put binding.pry where you want the breakpoint.

Rails 3 - NoMethodError: undefined method for nil:NilClass in each Iteration

I'm iterating over an array of instances of a Rails model. Here is my code:
product_details.each do |product_detail|
product_detail.label = Backend::ProductGroup.where(product_group_number: product_detail.product_group).first.label
end
The attribute 'label' from 'product_detail' isn't an attribute from my Rails ActiveRecord model. I added it with attr_accessor in my class definition. I did this, because I wanted to add this attribute dynamically, only when I need to do this. When I ran the code without the 'each' iteration in my rails console it works just fine. But when I execute the above code I get the following error message:
NoMethodError: undefined method 'label' for nil:NilClass
Did I do something obviously wrong?
Many thanks in advance.
You likely have several product_detail items that have no matching product_group. So calling .first on the empty collection returns nil. To get around the error, you can test if the product_group was found before proceeding:
product_details.each do |product_detail|
product_group = Backend::ProductGroup.where(product_group_number: product_detail.product_group).first
product_detail.label = product_group.label if product_group
end
You can also do this more efficiently like so:
group_labels = BackEnd::ProductGroup.
where(product_group_number: product_details.map(&:product_group)).
inject({}){|m, g| m[g.product_group_number] = g.label; m}
product_details.each do |product_detail|
product_detail.label = group_labels[product_detail.product_group]
end
This will result in a single database call to grab all related groups, and put the labels in a keyed hash for easy discovery and assignment.

Check for nil gives error

I have this line in my controller:
user = User.any_of({:user_name => login}, {:email => login})
if user.nil?
# ...
elsif user.legacy_password.nil?
And it creates this error:
undefined method `legacy_password' for []:Array
Why would this happen? the user object is supposed to be nil. At least that is what the debugger said.
I'm assuming your any_of method returns an array of results, not a single result. You probably want to add .first to the end of it, which will give you either a User record, or nil if any_of returned an empty array.
user = User.any_of({:user_name => login},{:email => login}).first
Looks like you are using mongoid (#any_of) and it's returning an array.
The error is because you are calling legacy_password on an array, but I assume it is defined on the User model.

Resources