Last Updated: June 08, 2016
·
9.556K
· psycatham

Fixing 'The Map doesn't Show up until I refresh' when working with Turbolinks in Ruby on Rails

I ran into this problem like while ago and barely found a practical solution.

This problem consists of a "conflict" between the Google Maps API and the Turbolinks gem.

For more details about the problem , visit this link

So, to avoid this conflict , you'll need to install jQuery.turbolinks.

To do so , follow the indications in here
or if you are in a hurry to read all of that ,
In your gemfile, add :

gem 'jquery-turbolinks'

and then save it, and run bundle install.

Afterwards, go to your application.js in assets/javascripts/

And put //= require jquery.turbolinks between //= require jquery and //= require turbolinks

This way :

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require twitter/bootstrap
//........... other javascripts files here
//= require turbolinks

Now you are ready to set the code.

As you know , the Google Maps API loads the *Map Loader * first via the link that you get, and then you call for the function that shows the map via :

google.maps.event.addDomListener(window, 'load', initialize);

We'll do quite the same thing, except that we'll do it with respect to our situation's parameters.

We'll call for the map loader, and only when the map loader has loaded, and the page is loaded and ready, then we'll call for the map.

First, in the same js file that contains your initialize function, define a variable (make it global)and asign this function to it. (I decided to call the variable ready)

ready = function() {
 var script = document.createElement('script');
 script.type = 'text/javascript';
 script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +'libraries=places&'+'callback=initialize';
   document.body.appendChild(script);
  };

What is this function doing is that it creates a script element to contain the link to the map loader, and in adds this fragment &callback=initialize to it. This fragment is what calls for the 'map shower' after the 'map loader' has finished loading.

Now we'll go the part where we load this stuff when the page has finished loading.

We'll use $.getScript() to make use of the variable we used, and we'll use $(document).ready to ensure that the page has finished loading (the first load), and then we'll use $(document).on('page:load') to load the map loader and show map upon page changement(second loadings and many more loadings).

What you'll do (what I prefer , and recommend you'd do) is to put it at the bottom of your layout page.

$.getScript('/assets/You_Js_File_name',function(){
                $(document).ready(ready); //calls for the function we defined above (first loading)
                $(document).on('page:load',ready); // the same but for the other loadings
              });

Save it , refresh the page, the map shows, go to other parts of the website, comeback to the map page, it loads properly. Yay.

I hope I helped.

For more in-depth and well-detailed documentation about such problems visits:
link1
link2

PS : There are many solutions out there, but they did not worked for me for a reason or another, so I came up with mine, and it worked pretty fine, this post intends to share my experience with the problem, with regard that I am no professional, just a beginner learner who struggled pretty much with it and decided to share his solution

Thanks.

Have a fresh tip? Share with Coderwall community!

Post
Post a tip