ruby on rails - Google maps autocomplete js is working on localhost but not on heroku -


i'm junior ruby on rails developer. developed web app uses google maps javascript api , use autocomplete function on form input.

the autocomplete works fine on localhost not work anymore after deploying on heroku.

here html.erb below. perfect information, form in page footer. form partially hidden , visible part corresponds button used upload video file. once button has been clicked , video file has been chosen, display modal containing rest of form. that's 'text_field_tag' (with id = "user_input_autocomplete_address") displayed , autocomplete should work.

<% if user_signed_in? %>    <div class="footer-check hidden-md hidden-lg">    <div class="container text-right">      <div class="row">        <div class="flexbox">          <div class="footer-home active">            <%= link_to root_path %>              <i class="fa fa-home" aria-hidden="true"></i>            <% end %>          </div>          <div class="footer-search">          <!-- later put link_to reviews_path -->            <%= link_to search_path %>              <i class="fa fa-search" aria-hidden="true"></i>            <% end %>          </div>          <div class="footer-button">          <%= simple_form_for(review.new) |f| %>            <div id="add_video_image_btn">              <label for="review_video", class="add_video_image"><%= image_tag "plus.png" %></label>              <%= f.input :video, label: false, input_html: { accept: ".mp4, .mov, .m4v, .wmv, .webm, .avi", class: 'hidden'} %>              <%= f.input :video_cache, as: :hidden, class: "add_video_image file required" %>            </div>          </div>          <div class="footer-likes">            <%= link_to dashboard_users_path %>              <i class="fa fa-heart" aria-hidden="true"></i>            <% end %>          </div>            <div class="footer-user">            <%= link_to user_path(current_user) %>              <i class="fa fa-user" aria-hidden="true"></i>            <% end %>          </div>        </div>      </div>    </div>  </div>    <!--beginning modal -->  <div class="modal fade" id="mymodal" tabindex="-1" role="dialog" aria-labelledby="mymodallabel">  <div class="modal-dialog" role="document">    <div class="modal-content">      <div class="modal-body">        <div id="add_video_form_step2">          <%= f.error_notification %>            <fieldset class="form-group" style="margin-bottom:0;">              <div class="section">              place            </div>            <div class="inner-wrap">              <div id="">                <%= text_field_tag :place, nil, class: 'form-control', id: 'user_input_autocomplete_address', placeholder: 'start typing...', size: 80 %>              </div>            </div>              <div class="section">              comment            </div>            <div class="inner-wrap">              <%= text_field_tag :comment, nil, class:'form-control', placeholder: 'food place bit noisy', size: 80 %>            </div>              <div class="inner-wrap" style="padding:15px;">              <div class="emoji-toggle emoji-happy">                <input type="checkbox" id="toggle1" class="toggle" name="review[mood]" value="false">                <div class="emoji"></div>                <label for="toggle1" class="well"></label>              </div>            </div>              <div class="">              <%= f.button :submit, class: "btn btn-primary form-control", id: "click-trigger" %>            </div>              <%= hidden_field_tag :name, id: 'name' %>            <%= hidden_field_tag :street_number, id: 'street_number' %>            <%= hidden_field_tag :route, id: 'route' %>            <%= hidden_field_tag :locality, id: 'locality' %>            <%= hidden_field_tag :administrative_area_level_1, id: 'administrative_area_level_1' %>            <%= hidden_field_tag :postal_code, id: 'category_0' %>            <%= hidden_field_tag :country, id: 'country' %>            <%= hidden_field_tag :formatted_address, id: 'formatted_address' %>            <%= hidden_field_tag :phone_number, id: 'phone_number' %>            <%= hidden_field_tag :website, id: 'website' %>            <%= hidden_field_tag :gplace_id, id: 'gplace_id' %>            <%= hidden_field_tag :category_0, id: 'category_0' %>            <%= hidden_field_tag :category_1, id: 'category_1' %>            <%= hidden_field_tag :category_2, id: 'category_2' %>            <%= hidden_field_tag :category_3, id: 'category_3' %>            <%= hidden_field_tag :category_4, id: 'category_4' %>            <%= hidden_field_tag :category_5, id: 'category_5' %>            <%= hidden_field_tag :hours_open_day_0, id: 'hours_open_day_0' %>            <%= hidden_field_tag :hours_open_day_1, id: 'hours_open_day_1' %>            <%= hidden_field_tag :hours_open_day_2, id: 'hours_open_day_2' %>            <%= hidden_field_tag :hours_open_day_3, id: 'hours_open_day_3' %>            <%= hidden_field_tag :hours_open_day_4, id: 'hours_open_day_4' %>            <%= hidden_field_tag :hours_open_day_5, id: 'hours_open_day_5' %>            <%= hidden_field_tag :hours_open_day_6, id: 'hours_open_day_6' %>          </fieldset>        </div>      </div>      </div>    </div>  </div>          </div>        </div>      </div>    </div>  <% end %>  <% end %>    <!--end modal -->    <!-- start of js display modal -->  <!-- nb: autocomplete module in assets/javascript/autocomplete.js -->  <%= content_for :after_js %>    <script>      $('#review_video').change(function(){        $('#mymodal').modal('show');      });    </script>  <% end %>  <!-- end of js display modal -->

the footer (gathering modal , form) called within layouts/application.html.erb view, below. you'll see use google api key in there (hidden in application.yml)

<!doctype html>  <html>    <head>      <title><%= meta_title %></title>      <%= csrf_meta_tags %>        <!-- start favicon -->        <%= favicon_link_tag '_/app/assets/images/favicon.ico' %>        <link rel="manifest" href="/manifest.json">      <meta name="msapplication-tilecolor" content="#ffffff">      <meta name="msapplication-tileimage" content="<%= image_path 'ms-icon-144x144.png' %>">      <meta name="theme-color" content="#ffffff">      <!-- end favicon -->        <meta name="description" content="<%= meta_description %>">        <!-- facebook open graph data -->      <meta property="og:title" content="<%= meta_title %>" />      <meta property="og:type" content="website" />      <meta property="og:url" content="<%= request.original_url %>" />      <meta property="og:image" content="<%= meta_image %>" />      <meta property="og:description" content="<%= meta_description %>" />      <meta property="og:site_name" content="<%= meta_title %>" />        <!-- twitter card data -->      <meta name="twitter:card" content="summary_large_image">      <meta name="twitter:site" content="<%= default_meta["twitter_account"] %>">      <meta name="twitter:title" content="<%= meta_title %>">      <meta name="twitter:description" content="<%= meta_description %>">      <meta name="twitter:creator" content="<%= default_meta["twitter_account"] %>">      <meta name="twitter:image:src" content="<%= meta_image %>">        <!-- google+ schema.org markup -->      <meta itemprop="name" content="<%= meta_title %>">      <meta itemprop="description" content="<%= meta_description %>">      <meta itemprop="image" content="<%= meta_image %>">            <meta name="viewport" content="width=device-width, initial-scale=1">      <meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1">      <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">      <%= stylesheet_link_tag    'application', media: 'all' %>      <meta http-equiv="content-type" content="text/html; charset=utf-8">        <!-- start mixpanel -->      <script type="text/javascript">(function(e,b){if(!b.__sv){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.tostring=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.tostring=function(){return c.tostring(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");        for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__sv=1.2;a=e.createelement("script");a.type="text/javascript";a.async=!0;a.src="undefined"!==typeof mixpanel_custom_lib_url?mixpanel_custom_lib_url:"file:"===e.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";f=e.getelementsbytagname("script")[0];f.parentnode.insertbefore(a,f)}})(document,window.mixpanel||[]);        mixpanel.init("env['mixpanel_token']");      </script>      <!-- end mixpanel -->      </head>    <body>      <%= render 'shared/flashes' %>      <%= yield %>      <%= render 'shared/footer' %>      <%= javascript_include_tag "http://maps.google.com/maps/api/js?libraries=places&key=#{env['gmap_browser_key']}" %>      <%= javascript_include_tag "http://cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js" %>      <%= javascript_include_tag 'application' %>      <%= yield :after_js %>    </body>  </html>

last, javascript code allowing autocomplete on input (having "user_input_autocomplete_address" id) in assets/javascript/autocomplete.js , following :

function initializeautocomplete(id) {    var element = document.getelementbyid(id);    console.log('coucou');    if (element) {      var autocomplete = new google.maps.places.autocomplete(element, { types: ['geocode', 'establishment'] });      google.maps.event.addlistener(autocomplete, 'place_changed', onplacechanged);    }  }    function onplacechanged() {    var place = this.getplace();      console.log(place);  // uncomment line view full object returned google api.      (var in place.address_components) {      var component = place.address_components[i];      // console.log(component.types);      (var j in component.types) {  // types ["country", "political"]        var type_element = document.getelementbyid(component.types[j]); // returns div differents ids or null if id doesnt exist        // console.log(document.getelementbyid(component.types[j]));        if (type_element) {          type_element.value = component.long_name;        }      }    }      var formatted_address = document.getelementbyid('formatted_address');    // console.log(international_phone_number);    if (formatted_address) {      formatted_address.value = place.formatted_address;    }      (var in place.types) {      // console.log(place.types);      // console.log(i);      // console.log(place.types[i]);      var type_content = document.getelementbyid('category_' + i); // returns div differents ids or null if id doesnt exist      // console.log(document.getelementbyid(component.types[j]));      if (type_content) {        console.log(place.types[i]);        type_content.value = place.types[i];      }    }      var international_phone_number = document.getelementbyid('phone_number');    // console.log(international_phone_number);    if (international_phone_number) {      international_phone_number.value = place.international_phone_number;    }      var name = document.getelementbyid('name');    if (name) {      name.value = place.name;    }      var gplace_id = document.getelementbyid('gplace_id');    if (gplace_id) {      gplace_id.value = place.place_id;    }      var website = document.getelementbyid('website');    if (website) {      website.value = place.website;    }      (var in place.opening_hours.weekday_text) {      var hours_open_in_db = place.opening_hours.weekday_text[i];      var hours_open_in_form = document.getelementbyid('hours_open_day_' + i);      if (hours_open_in_form) {        hours_open_in_form.value = hours_open_in_db;      }    }  }    google.maps.event.adddomlistener(window, 'load', function() {    initializeautocomplete('user_input_autocomplete_address');  });

in order deploy on heroku, did following :

  1. "heroku run db:migrate" in terminal (because had pending migrations);
  2. "figaro heroku:set -e production" in terminal, in order push api keys heroku (i checked these keys indeed in heroku's config vars).
  3. in google's developer console, within project , within google map javascript api, ensured browser key allowed both locahost , domain name. in order precise, using same key locahost , domain name. until now, thing have not managed yet, in google's console, prove own domain name.
  4. i checked have not reached of api quotas yet.
  5. within autocomplete.js file, used console.log in order find out, in browser's inspector, parts of code working. seems works except console.logs in 'onplacechange' callback, since gmap's autocomplete suggestions not shown... ;
  6. i know not seeing autocomplete suggestions not problem of z-index associated .pac-container css element, since had fix , since gmaps suggestions cannot reached keyboard arrows.
  7. i read post geocomplete (geocomplete rails 4 not working in heroku) , tried precompile assets. did not lead change.
  8. in browser inspector (in 'network' section), when write in form input, every new letter pressed on keyboard triggers new request. these requests names 'autocompletionservice.getpredictions.....'. in "headers" section, can see https requests googleapis, methods , 200 status code. in "response" section, can see there seems error api keys since message :

/**/_xdc_._ty4oqn && _xdc_._ty4oqn( [3,null,null,"this api project not authorized use api. please ensure api activated in apis console: https://console.developers.google.com/apis/library?project=_ please ensure api activated in google developers console: https://console.developers.google.com/apis/api/places_backend?project=_ more information on authentication , google maps javascript api services please see: https://developers.google.com/maps/documentation/javascript/get-api-key"] )
followed link in error message, leading me google's console, , project , api keys, settled both server-side , browser-side. once again, thing did not managed in google's console prove own domain name.

is last point origin of issue (and in case guess need hosting services) or guys see mistake?

i has same issue too. goto google console, enable "google places api web service", solved problem.


Comments

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -