Search code examples
google-mapsreactjsreactjs-fluxflux

Global window Actions in Flux pattern


Background

I'm looking to implement a flux store to manage async 3rd party scripts (current use case is the google maps API)

I want to be able to have my maps component check with the store for the api state and manage external scripts in this way rather than piling them inline to always load, to only load a script when it's needed by the first component

It will just do something like:

script         = document.createElement('script')
script.async   = 'async'
script.src     = src
script.onload  = () =>
  // update state and emmit change event

document.getElementsByTagName('head')[0].appendChild(@script)

The issue

The google maps script accepts a callback which will run once the script has initialised, which is where I want to update my store.

This callback will need to exist globally on the window, however, I don't really want to expose any of the Actions directly to the window.

The Question

Is there any recommended pattern to expose a global callback for google maps to hit on init, which can then update my Stores state, whilst still going through my AppDispatcher?


Solution

  • You can always assign globals in your store when it's created.

    Something like:

    function createStore() {
      window.initializeGoogleMaps = function () {
        window.initializeGoogleMaps = null;
    
        // Tell the world that Google Maps loaded
      };
    
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' +
                   '&signed_in=true&callback=initializeGoogleMaps';
      document.body.appendChild(script);
    
      return {
        doStuff: function () {
    
        }
      };
    }
    

    That way, the global is contained in that function, and it's removed when the callback is called. The rest of your app won't see it, and you don't have to touch any other files to change it.