import { Meteor } from 'meteor/meteor'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import GoogleMapsLoader from 'google-maps'; class GkeysC { constructor() { this.gmapkey = new ReactiveVar(null); // Separate from the key itself: a deployment with no gmaps key configured // still loads the script and still has to render. Waiting on the key value // meant that with an empty key every component mounted after the script had // loaded (i.e. any client-side navigation) sat forever on "Waiting for the // gkey" and rendered an empty
— /subscriptions/new was blank, with no // error anywhere. this.loaded = new ReactiveVar(false); const self = this; this.callbacks = []; Meteor.startup(() => { Meteor.call('getMapKey', (error, key) => { // console.log(google.maps); GoogleMapsLoader.KEY = key; GoogleMapsLoader.LIBRARIES = ['places']; // The google-maps npm package (v3.2.1) builds the script URL without // `loading=async`, which Google now warns about. It exposes no hook for // extra params, so wrap createUrl to append it (no node_modules edit). const origCreateUrl = GoogleMapsLoader.createUrl; GoogleMapsLoader.createUrl = () => `${origCreateUrl()}&loading=async`; GoogleMapsLoader.load(() => { self.gmapkey.set(key); self.loaded.set(true); console.log('GMaps script just loaded'); self.doCallbacks(key); }); }); }); } doCallbacks(key) { for (let i = 0; i < this.callbacks.length; i += 1) { this.callbacks[i](null, key); } this.callbacks = []; } load(callback) { this.callbacks.push(callback); Tracker.autorun((computation) => { if (this.loaded.get()) { // already loaded; the key may legitimately be empty this.doCallbacks(this.gmapkey.get()); computation.stop(); } else { console.log('Waiting for the gmaps script'); } }); } } const Gkeys = new GkeysC(); export default Gkeys;