Why am I getting undefined method error ruby? - ruby

require "rubygems"
require "json"
require "net/http"
require "uri"
uri = URI.parse("https://api.website.com/top/inside/end")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
http.use_ssl = true
response = http.request(request)
if response.code == "200"
result = JSON.parse(response.body)
names = Array.new
i = 0
result.each do |doc|
names.insert(i, doc.name)
puts doc["id"] #reference properties like this
puts doc # this is the result in object form
puts ""
puts ""
end
puts names
else
puts "ERROR!!!"
end
Why am I getting undefined method error on variable names inside the for each loop? I cannot understand why
script.rb:18:in `block in ': undefined method `name' for #<Hash:0x0000000002e04c08> (NoMethodError)

line 18,
names.insert(i, doc.name)
doc is a Hash, doc['name'] should works.
in javascript, you can do
doc.name

Related

undefined local variable or method `http' for main:Object (NameError)

File: nethttp.rb
require 'uri'
require 'net/http'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
uri = URI('http://localhost/events',:headers => headers)
res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)
I'm receiving the error:
undefined local variable or method `http' for main:Object (NameError)
You're using the local variable http which is not declared anywhere in the code. If you want to create an instance of Net::HTTP you need to use the "new" method:
require 'uri'
require 'net/http'
# URI only takes one argument!
uri = URI('http://localhost/events')
http = Net::HTTP.new(uri)
# not sure what this is supposed to do since you're requesting a
# HTTP uri and not HTTPS
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# ...
But you might want to consider using Net::HTTP.start which opens a connection and yields it to the block:
require 'uri'
require 'net/http'
uri = URI('http://localhost/events')
# Opens a persisent connection to the host
Net::HTTP.start(uri.host, uri.port, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
headers = { "X-FOO" => "Bar" }
request = http.get(uri)
headers.each do |key, value|
request[key] = value
end
response = http.request(request)
# consider using a case statement
if response.is_a?(Net::HTTPSuccess)
puts response.body
else
# handle errors
end
end

How To change a URI object's path attribute?

I want to call an API using only slightly different URIs. This code snippet does what I want, but I want to know if there is a more efficient way to do it.
require 'net/http'
require 'json'
# These URIs differ only in the path
orders = URI('https://hft-api.lykke.com/api/Orders?orderType=Unknown')
asset_pairs = URI('https://hft-api.lykke.com/api/AssetPairs')
lykke_req = Net::HTTP::Get.new(orders)
lykke_req['User-Agent'] = 'curl/7.67.0'
lykke_req['api-key'] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
lykke_req['Accept'] = 'application/json'
response = Net::HTTP.start(orders.hostname,
orders.port,
:use_ssl => true) {|http| http.request(lykke_req)}
puts JSON.parse(response.body)
lykke_req = Net::HTTP::Get.new(asset_pairs)
lykke_req['User-Agent'] = 'curl/7.67.0'
lykke_req['Accept'] = 'application/json'
response = Net::HTTP.start(asset_pairs.hostname,
asset_pairs.port,
:use_ssl => true) {|http| http.request(lykke_req)}
puts JSON.parse(response.body)
All I do is to reuse the same code but with a slightly different URI.
For my lykke_req objects, I can write
puts lykke_req
puts lykke_req.path
which gives me
#<Net::HTTP::Get:0x00007f947f1fdce8>
/api/Orders?orderType=Unknown
So it seems to me all i have to do is change the value of lykke_req.path. But I can't work out how to do it. I am looking for something like this
lykke_req.path = "/api/AssetPairs"
which fails with
undefined method `path=' for #<Net::HTTP::Get GET> (NoMethodError)
I found this on the official documentation page, but I can't find out what [R] means. Does it mean read only? Do I really have to go through the hassle of creating a new URI object, then creating a new Net::HTTP::Get object each time?
path [R]
The problem here is that you're trying to alter the net request object instead of the uri object:
irb(main):001:0> uri = URI('https://hft-api.lykke.com/api/Orders?orderType=Unknown')
=> #<URI::HTTPS https://hft-api.lykke.com/api/Orders?orderType=Unknown>
irb(main):002:0> uri.path = '/foo'
=> "/foo"
irb(main):003:0> uri.to_s
=> "https://hft-api.lykke.com/foo?orderType=Unknown"
But I would really just wrap this in a class so that you can encapsulate and structure your code and avoid duplication:
class LykkeAPIClient
BASE_URI = URI('https://hft-api.lykke.com/api')
def initalize(api_key:)
#api_key = api_key
end
def get_orders
get '/Orders?orderType=Unknown'
end
def get_asset_pairs
get '/AssetPairs'
end
def get(path)
req = Net::HTTP::Get.new(BASE_URI.join(path))
req['User-Agent'] = 'curl/7.67.0'
req['Accept'] = 'application/json'
req['api-key'] = #api_key
response = Net::HTTP.start(req.hostname, req.port, use_ssl: true) do |http|
http.request(uri)
end
# #todo check response status!
JSON.parse(response.body)
end
end
#client = LykkeAPIClient.new(api_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
#orders = #client.get_orders
Insstead of lykke_req.path= do lykke_req.uri.path=
https://ruby-doc.org/stdlib-2.6.5/libdoc/net/http/rdoc/Net/HTTPGenericRequest.html

Convert HTTP response to JSON in Ruby

I'm doing a GET request and getting this response:
"oauth_token=USYS96A708CACBDA9C74322DAB41A53CA_idses-int02.a.fsglobal.net&oauth_token_secret=09c8b05b874fac29b4e542c388cb3f&oauth_callback_confirmed=true"
How can I convert this to JSON in Ruby?
Step 1: Parse the GET response:
require 'cgi'
CGI::parse(MYSTRING)
Returns: {"param1"=>["value1"], "param2"=>["value2"], "param3"=>["value3"]}
Step 2. Convert to JSON:
require 'json'
myObject.to_json
Alternatively, look at this snippet:
https://gist.github.com/timsavery/1657351
require "rubygems"
require "json"
require "net/http"
require "uri"
uri = URI.parse("http://api.sejmometr.pl/posiedzenia/BZfWZ/projekty")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
if response.code == "200"
result = JSON.parse(response.body)
result.each do |doc|
puts doc["id"] #reference properties like this
puts doc # this is the result in object form
puts ""
puts ""
end
else
puts "ERROR!!!"
end

Ruby making a web request

Hi this is my very first Ruby program.
I'm trying to write a simple ruby app to make a request to a URL and see if it's available. If it is, it'll print OK and else it'll print false.
This is what I've got so far, can you please assist, do I need to import any libs?
class WebRequest
def initialize(name)
#name = name.capitalize
end
def makeRequest
puts "Hello #{#name}!"
#uri = URI.parse("https://example.com/some/path")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # read into this
#data = http.get(uri.request_uri)
end
end
req = WebRequest.new("Archie")
req.makeRequest
Here is sample code to do any request:
require 'net/http'
require 'uri'
url = URI.parse('http://www.example.com/index.html')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
puts res.body
gem install httparty
then
require 'httparty'
response = HTTParty.get('https://example.com/some/pathm')
puts response.body
Something simpler:
[1] pry(main)> require 'open-uri'
=> true
[2] pry(main)> payload = open('http://www.google.com')
=> #<File:/var/folders/2p/24pztc5s63d69hhx81002bq80000gn/T/open-uri20131217-84948-ttwnho>
[3] pry(main)> payload.inspect
=> "#<Tempfile:/var/folders/2p/24pztc5s63d69hhx81002bq80000gn/T/open-uri20131217-84948-ttwnho>"
[4] pry(main)> payload.read
payload.read would return the response body and you can easy use payload as File object since it is an instance of Tempfile
This is what I've ended up with
require 'net/http'
class WebRequest
def initialize()
#url_addr = 'http://www.google.com/'
end
def makeRequest
puts ""
begin
url = URI.parse(#url_addr)
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
puts "OK Connected to #{#url_addr} with status code #{res.code}"
rescue
puts "Failed to connect to #{#url_addr}"
end
end
end
req = WebRequest.new()
req.makeRequest

syntax error, unexpected end-of-input, expecting keyword_end

I'm trying to write a simple program to parse JSON from the results of an API call. Very new to ruby and just can't figure this one out.
Here's all the code:
require "rubygems"
require "json"
require "net/http"
require "uri"
uri = URI.parse("http://api.chartbeat.com/live/recent/v3/?apikey=eaafffb9a735796b6edd50fd31eaab69&host=enactus.org")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
if response.code == "200"
result = JSON.parse(response.body)
result.each do |doc|
puts doc["id"] #reference properties like this
puts doc # this is the result in object form
puts ""
puts ""
end
else
puts "ERROR!!!"
end
Here's the output of running the program (chartbeat.rb):
chartbeat.rb:14: syntax error, unexpected end-of-input, expecting keyword_end
The program comes verbatim from here with the url replaced: https://gist.github.com/timsavery/1657351
It doesn't look like what you're doing is taking advantage of any of Net::HTTPs power, so I'd probably do it like this:
require "rubygems"
require "json"
require "open-uri"
response = open("http://api.chartbeat.com/live/recent/v3/?apikey=eaafffb9a735796b6edd50fd31eaab69&host=enactus.org").read
result = JSON.parse(response)
result.each do |doc|
puts doc["id"] #reference properties like this
puts doc # this is the result in object form
puts ""
puts ""
end
OpenURI is the basis of a lot of code that hits URLs, and is a great starting place.
If you want to trap exceptions raised, use something like:
begin
response = open("http://api.chartbeat.com/live/recent/v3/?apikey=eaafffb9a735796b6edd50fd31eaab69&host=enactus.org").read
rescue Exception => e
puts e.message
exit
end
It could even be reduced to:
require "rubygems"
require "json"
require "open-uri"
JSON[
open("http://api.chartbeat.com/live/recent/v3/?apikey=eaafffb9a735796b6edd50fd31eaab69&host=enactus.org").read
].each do |doc|
puts doc["id"] #reference properties like this
puts doc # this is the result in object form
puts ""
puts ""
end
But that might be too drastic.

Resources