At the moment I have a simple app that consumes an external API and allows a user to query and return json. It returns all keys/values but I would only like it to return lat
and lon
in json, or at least I would only like to show these two in my view. Here is my code:
locationiq_api.rb
class LocationiqApi
include HTTParty
BASE_URI = "https://eu1.locationiq.com/v1/search.php"
attr_accessor :city
def initialize(api_key, format = "json")
@options = { key: api_key, format: format }
end
def find_coordinates(city)
self.class.get(BASE_URI, query: @options.merge({ q: city }))
end
def handle_error
if find_coordinates.code.to_i = 200
find_coordinates.parsed_response
else
raise "Couldn't connect to LocationIQ Api"
end
end
end
locations_controller.rb
class LocationsController < ApplicationController
def index
@search = LocationiqApi.new("pk.29313e52bff0240b650bb0573332121e").find_coordinates(params[:q])
end
end
locations.html.erb
<main>
<h1>Location Search</h1>
<!-- Button to search find coordinates -->
<%= form_tag(locations_path, method: :get) do %>
<%= label_tag(:q, "Search: ") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Find coordinates") %>
<% end %><br>
<h2>Search results:</h2>
</main>
<%= @search %>
Returned json:
[{"place_id":"100066","licence":"https:\/\/locationiq.com\/attribution","osm_type":"node","osm_id":"107775","boundingbox":["51.3473219","51.6673219","-0.2876474","0.0323526"],"lat":"51.5073219","lon":"-0.1276474","display_name":"London, Greater London, England, SW1A 2DX, United Kingdom","class":"place","type":"city","importance":0.9654895765402,"icon":"https:\/\/locationiq.org\/static\/images\/mapicons\/poi_place_city.p.20.png"}]
Supposing you have a JSON string that looks something like, as an example, this:
"[{\"place_id\":\"100066\",\"lat\":\"51.5073219\",\"lon\":\"-0.1276474\",\"class\":\"place\",\"type\":\"city\"}]"
Then you should be able to do (roughly speaking):
JSON.dump(
JSON.
parse(
"[{\"place_id\":\"100066\",\"lat\":\"51.5073219\",\"lon\":\"-0.1276474\",\"class\":\"place\",\"type\":\"city\"}]"
).
first.
slice('lat', 'lon')
)
This should give you:
=> "{\"lat\":\"51.5073219\",\"lon\":\"-0.1276474\"}"
Now, I recall that HTTParty may already convert the API reponse to a Ruby object (array or hash), so that JSON.dump
may not be needed. And, there might be other fiddles you would like to do (eg, you could use with_indifferent_access
if you prefer working with symbols as keys instead of strings).
Just to be clear, if you want this to be part of your class method, then you might do something like:
class LocationiqApi
include HTTParty
BASE_URI = "https://eu1.locationiq.com/v1/search.php"
attr_accessor :city
def initialize(api_key, format = "json")
@options = { key: api_key, format: format }
end
def find_coordinates(city)
JSON.dump(
JSON.
parse(
self.class.get(BASE_URI, query: @options.merge({ q: city }))
).
first.
slice('lat', 'lon')
)
end
def handle_error
if find_coordinates.code.to_i = 200
find_coordinates.parsed_response
else
raise "Couldn't connect to LocationIQ Api"
end
end
end
If self.class.get(BASE_URI, query: @options.merge({ q: city }))
returns anything other than a valid JSON
string that represents an array
of hashes
, then this will probably fail.
I suppose the key bits are:
hash
from your array
of hashes (assuming an array of hashes is always the result of the parsing);slice
to use only those key-value pairs you want;JSON.dump
. You could also use, I suppose, to_json
. Whichever floats your boat.Try this:
@search.map {|r| {lat: r['lat'], lon: r['lon']} }
Will be an array of hashes
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.