Can't load script correctly



  • I stumbled upon a weird behaviour, when I define the Google Maps js file in getScripts there is no error, but there is no script tag added and so the file will not be loaded,

        getScripts: function () {
            console.log("https://maps.googleapis.com/maps/api/js?key=" + this.config.map_api_key);
            return ["https://maps.googleapis.com/maps/api/js?key=" + this.config.map_api_key];
        },
    

    My first thought was, that the config object isn’t ready yet but the log shows the api key, so that’s not the problem, but I get a black screen, none of the modules will display.

    Currently I add the script tag myself in the start method and everything works fine, but this isn’t the desired approach.

    start: function () {
            Log.info("Starting module: " + this.name);
            var script = document.createElement("script");
            script.src = "https://maps.googleapis.com/maps/api/js?key=" + this.config.map_api_key;
            document.querySelector("body").appendChild(script);
            this.sendSocketNotification("CONFIG", this.config);
        },
    

    Any ideas?



  • @strawberry-3-141 I encountered the same issue when trying to create a map the showing the route of the last Strava activity.

    To continue using google maps, my solution was a little more complex, but if I recall correctly allowed me to specify a callback when loading the Google Maps API. Though I hadn’t thought about loading it in the start function :) :

        start: function() {
            this.mapId = this.identifier + "_gmap";
            Log.log(this.name + ' is started!');
        },
    
        // Override dom generator.
        getDom: function() {
            var self = this;
            var wrapper = document.createElement("div");
            var map = document.createElement("div");
            map.id = this.mapId;
            map.classList.add("map-canvas");
            map.style.height = "200px";
            map.style.width = "200px";
            wrapper.appendChild(map);
    
            this.getScript('https://www.google.com/jsapi', function() { 
                google.load('maps', '3', { other_params: 'key=' + self.config.google_maps_key, callback: function() {
                    self.initMap();
                }});
            });
            
            return wrapper;
        },
        
        initMap: function() {
            if (typeof google === 'object' && typeof google.maps === 'object') {
                // Create map
                //var mapContainer = document.getElementById(this.mapId);
                var map = new google.maps.Map(document.getElementById(this.mapId), {
                  backgroundColor: 'none',
                });
                map.setZoom(8);
                map.setCenter(new google.maps.LatLng(37.4419, -122.1419));
            }
        },
        
        getScript: function(source, callback) {
          var script = document.createElement('script');
          var prior = document.getElementsByTagName('script')[0];
          script.async = 1;
          prior.parentNode.insertBefore(script, prior);
      
          script.onload = script.onreadystatechange = function( _, isAbort ) {
              if(isAbort || !script.readyState || /loaded|complete/.test(script.readyState) ) {
                  script.onload = script.onreadystatechange = null;
                  script = undefined;
      
                  if(!isAbort) { if(callback) callback(); }
              }
          };
      
          script.src = source;
        }
    

    In the end I have currently settled on using Leaflet.js - which, depending on which tile layer you use, has the added benefit of not requiring API keys (one less thing for users to configure), can be loaded locally (and via the getScripts function) and there are existing black and white/grayscale map tiles available which compliment the Mirror.

        // Subclass getScripts method.
        getScripts: function() {
            return [
                this.file('js/leaflet.js'),
            ];
        },
    

    Hope this helps a little


  • Moderator

    This post is deleted!


  • You can get leaflet to work in magic mirror quite easily. When you are creating your getDom function take the example from the tutorial as follows:

    var mymap = L.map('mapid').setView([51.505, -0.09], 13);
    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
                attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
                maxZoom: 18,
                id: 'mapbox.streets',
                accessToken: Your Access token
            }).addTo(this.mymap);
    

    You will also need specify the size of the of the map window in your css file

    .Your_Module_Name #mapid {
        height: 500px;
        width: 500px;
    }
    

    There is a bit of a bug with some of the map not loading, this can be fixed by listening for the DOM_OBJECTS_CREATED notification like so:

    notificationReceived: function (notification, payload, sender) {
            if (notification === "DOM_OBJECTS_CREATED") {
                this.mymap.invalidateSize();
            }
        },
    

    This forces a redraw of the map.


Log in to reply
 

Looks like your connection to MagicMirror Forum was lost, please wait while we try to reconnect.