1

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:

Community
  • 1
  • 1
Max Dubinin
  • 214
  • 3
  • 20

2 Answers2

3

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)
max
  • 96,212
  • 14
  • 104
  • 165
  • yeah I should have mentioned that I tried that and didn't manage to make this request because it's cross domain and every way to fix that didn't work. I opened a different thread about that... – Max Dubinin May 17 '16 at 03:38
  • Then setup your rails app to proxy the request. You need a controller action and a route - not a helper. But you're doing something very wrong if you cant do a cross domain request to google maps API - it sends CORS headers. – max May 17 '16 at 08:40
  • can you explain a bit further please? here is my question about CORS http://stackoverflow.com/questions/37255085/rails-cross-domain-ajax-get-request-cors – Max Dubinin May 17 '16 at 08:50
0

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)
            });
        });
    }
  }
Max Dubinin
  • 214
  • 3
  • 20