ruby-on-railsgmaps4railsruby-on-rails-6

Rails 6 and Google Maps for Rails


I'm using Rails 6.0.0.rc1 and hoping to implement the Google-Maps-for-Rails gem. I installed underscore via Yarn and added the required google scripts with my API in my tag.

I download the gmaps_google.js and added it to my vendor/js folder as Rails 6 has no asset pipeline, instead uses webpacker. This is where I think to issue is as I get the following error:

ReferenceError: Can't find variable: Gmaps

I updated my webpacker.yml file to look for the vendor/js folder and when checking the DOM it seems to be present.

webpacker.yml

# Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
resolved_paths: ['vendor/js']

In my javascript/packs/application.js I included a require("gmaps_google") line. Note, I had the same issue with Highcharts, but was able to load the script successfully but adding window.Highcharts = Highcharts; but I'm not sure if I can do the same with a require option?

javascript/packs/application.js

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery')
require("trix")
require("@rails/actiontext")

window.Highcharts = Highcharts;
import Highcharts from 'highcharts';
import addMore from "highcharts/highcharts-more";
import 'bootstrap'
import 'underscore'

require("gmaps_google")

package.json

{
  "name": "app_name",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0-alpha",
    "@rails/actiontext": "^6.0.0-rc1",
    "@rails/activestorage": "^6.0.0-alpha",
    "@rails/ujs": "^6.0.0-alpha",
    "@rails/webpacker": "^4.0.7",
    "bootstrap": "^4.3.1",
    "highcharts": "^7.1.2",
    "jquery": "^3.4.1",
    "popper.js": "^1.15.0",
    "trix": "^1.0.0",
    "turbolinks": "^5.2.0",
    "underscore": "^1.9.1"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.7.1"
  }

Solution

  • That's because of there aren't export statements in gmaps_google.js, you should convert anonymous functions to named function before that.

    As an example:

    // foo.js
    // function need to be converted
    (function() {
      // function body
    }).call(this);
    

    convert anonymous function to named function

    // foo.js
    function foo() {
      // function body
    };
    
    export { foo as Foo };
    

    invoke import statement in another file.

    // bar.js
    import Foo from 'foo';
    
    Foo();