Max Dubinin
Max Dubinin

Reputation: 224

Pass HTML5 geolocation to the controller

I want to get the user's coordinates using HTML5 Geolocation and send them to a helper method. Geocoder gem is not an option because the IP geolocation is not accurate enough for my application.

Is that possible? I'm using coffeescript and slim-lang

my helper method, located in application_helper.rb:

  def get_station(location)
    type = not relevant
    key = not relevant
    radius = 5000
    url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=#{location}&radius=#{radius}&type=#{type}&key=#{key}"
    data = JSON.load(open(url))["results"][0]["name"]
  end

the coffeescript part in my view (.slim template):

  set_location = ->
    if (navigator.geolocation)
      navigator.geolocation.getCurrentPosition(setLocation);

  setLocation = (position) ->
    coords = position.coords.latitude + ", " + position.coords.longitude;

Threads I reviewed before posting:

Upvotes: 1

Views: 1187

Answers (2)

Max Dubinin
Max Dubinin

Reputation: 224

It's not exactly answers the question itself but it does that I needed to do in the first place using AJAX and a controller method instead. It successfully passes the LAT,LNG params from HTML5 Geolocation to the controller method.

controller:

def location
    respond_to do |format|
      format.json {
        lat = params["lat"]
        lng = params["lng"]
        radius = 5000
        type = "restraunt"
        key = "-"
        url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=#{lat},#{lng}&radius=#{radius}&types=#{type}&key=#{key}"
        data = JSON.load(open(url))
        results = []
        data["results"].each do |result|
          results.push({ "name":result["name"], "vicinity":result["vicinity"], "lat":result["geometry"]["location"]["lat"], "lng":result["geometry"]["location"]["lng"] })
        end
        render json: { :data => results, :lat => lat, :lng => lng }
      }
    end
  end

routes.rb:

get "/location" => "application#location"

view:

function getLocation(){
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position){
          $.ajax({
            type: 'GET',
            url: '/location',
            data: { lat: position.coords.latitude, lng: position.coords.longitude },
            contentType: 'application/json',
            dataType: 'json'
            }).done(function(data){
               console.log(data)
            });
        });
    }
  }

Upvotes: 0

max
max

Reputation: 102222

You can't use your Rails helper method here.

Server side rendering is done before the script is sent to the user. So even if you used interpolation <%= get_station(location) %> would return the wrong results.

navigator.geolocation.getCurrentPosition is asynchronous - the callback is not actually called until the user allows geolocation. Instead let the client send the ajax request to the google maps API:

setLocation = (position) ->
  uri = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json'
  promise = $.ajax(uri,
    dataType: 'json'
    data:
      location: position.coords.latitude + ', ' + position.coords.longitude
      type: 'hindu_temple'
      radius: 5000
      key: 'Your google maps key'
  promise.done (data)->
    console.log(data)

Upvotes: 3

Related Questions