4

I'm trying to lazyload Google Maps in my AngularJS project. I see the map getting loaded async in the DOM when I inspect, but it doesn't appear in the viewport of my Chrome browser.

What am I missing?

Here is the plunker. http://embed.plnkr.co/5LYp91Wl7xrJ1QcNEN2W/preview

Here is the JS code for the factory and the directive:

(function() {
  'use strict';

  angular
    .module('myapp', [])
    .factory('mapsInit', mapsInitFactory)
    .directive('propertyMap', propertyMap);

  function mapsInitFactory($window, $q) {
    //Google's url for async maps initialization accepting callback function
    var asyncUrl = 'https://maps.googleapis.com/maps/api/js?callback=',
      mapsDefer = $q.defer();

    //Callback function - resolving promise after maps successfully loaded
    $window.googleMapsInitialized = mapsDefer.resolve; // removed ()

    //Async loader
    var asyncLoad = function(asyncUrl, callbackName) {
      var script = document.createElement('script');
      //script.type = 'text/javascript';
      script.src = asyncUrl + callbackName;
      document.body.appendChild(script);
    };

    //Start loading google maps
    asyncLoad(asyncUrl, 'googleMapsInitialized');

    //Usage: Initializer.mapsInitialized.then(callback)
    return {
      mapsInitialized: mapsDefer.promise
    };
  }

  function propertyMap(mapsInit) {
    return {
      restrict: 'E',
      scope: {
        mapId: '@id', // map ID
        lat: '@', // latitude
        long: '@' // longitude
      },
      link: function(scope) {
        // Simple check
        console.log(scope.mapId, scope.lat, scope.long);
        // Check if latitude and longitude are specified
        if (angular.isDefined(scope.lat) && angular.isDefined(scope.long)) {

          // Initialize the map
          var initialize = function() {

            var location = new google.maps.LatLng(scope.lat, scope.long);

            var mapOptions = {
              zoom: 12,
              center: location
            };

            var map = new google.maps.Map(document.getElementById(scope.mapId), mapOptions);

            new google.maps.Marker({
              position: location,
              map: map
            });
          };
          // Loads google map script
          mapsInit.mapsInitialized.then(function() {
            // Promised resolved
            initialize();
          }, function() {
            // Promise rejected
          });
        }
      }
    };

  }

})();

Here is the html (style.css is empty):

<!DOCTYPE html>
<html ng-app="myapp">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-init="working = true">
  <h1>Async Google Maps</h1> AngularJS works: {{working}}
  <property-map id="map-12345" lat="45.53315412" long="-73.61803162"></property-map>
</body>

</html>

1 Answer 1

3

I feel a fool but I simply had to add some style to property-map ;-)

property-map {
  display: block;
  background-color: #fafafa;
  height: 500px;
  width: 100%;
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.