2017-09-19 10 views
0

が定義されていません。マップは、私がジオコード機能を使用しようとするたびしかし、私はエラーにReferenceErrorを取得し、細かいロードされる:Googleはに定義されていません。Angularjs:GoogleマップAPIは - Googleは私がangularjs単一ページのアプリケーションに取り組んでいる、と私は、アプリケーションのマッピングシステムを構築しようとしている

(function() { 
    'use strict'; 

    angular 
     .module('CityWits') 
     .factory('mapApi', mapApi); 



    function mapApi() { 
     var mapApi = {} 
     var markers = []; 
     var geocoder; 
     var service; 


     mapApi.geocode = geocode; 
     mapApi.marker = marker; 
     mapApi.distance = distance; 
     return mapApi; 

     function geocode (addresses){ 
      geocoder = new google.maps.Geocoder(); 
      var coords = []; 
      if(geocoder){ 
       for(var i in addresses){ 
        geocoder.geocode({ 'address': addresses[i]}, function(results, status) { 

          if (status === 'OK') { 
          coords.push(results[0].geometry.location); 
          } else { 
          alert('Geocode was not successful for the following reason: ' + status); 
          } 
        }); 
       } 
      } 
     } 

     function distance(start, end, method="DRIVING"){ 
      service = new google.maps.DistanceMatrixService; 
      service.getDistanceMatrix({ 
       origins: start, 
       destinations: end, 
       travelMode: method 
      }, function (status, response){ 
       if(status ==! "OK"){ 
        console.log("Error: "+status); 
       } else { 
        console.log("distance measured"); 

        var result = {}; 
        for(var i in response.rows){ 
         result = response.rows[i].element; 
        } 
        return result; 
       } 
      }); 
     } 

     function marker(positions, json){ 
      if(markers.length > 0){ 
       for(o in markers){ 
        markers[o].setMap(null); 
       } 
      } 
      for(x in positions){ 

      } 
     } 

    } 


})(); 

そして最後に、これはAPIを開始ディレクティブです:

地図コントローラ

(function() { 
    'use strict'; 
    angular 
     .module('CityWits') 
     .controller('mapCtrl', mapCtrl); 

    mapCtrl.$inject = ['$scope', '$http', 'mapApi', '$q']; 

    function mapCtrl($scope, $http, mapApi, $q){ 
     var vm = this; 
     vm.setQuery = setQuery; 

     // todo: Switch this out with deals that are loaded depending on the radius of the map 


     getBranches(); 

     function setQuery(query) { 
      console.log("business deal filter controller : query=" + query); 
      vm.query = query; 
      vm.focus = false; 
     } 

     function getBranches(){ 
      $http.get('app/cwitsTestData/branchData.json').then(function(data){ 
       vm.branches = sortBranches(data.data.branches); 
       $scope.$broadcast("branchesSorted", vm.branches); 

      }); 
     } 

    } 
    function sortBranches(branches){ 
     var locations, address, text; 
     locations = []; 
     for(var branch in branches){ 
      address = branches[branch].address; 
      text = address.street_line1 + " " + address.city+ " " +address.state; 
      locations.push(text); 
     } 
     return locations; 
    } 

})(); 

は、ここで私は、APIを処理するために書いたGoogleの工場ですどうやら

(function() { 
    'use strict'; 
    angular 
     .module('CityWits') 
     .directive('dealMap', dealMap); 

    dealMap.$inject = ['$timeout', '$http', 'mapApi']; 

    function dealMap($timeout, $http, mapApi){ 
     var directive = { 
      link: link, 
      templateUrl: 'app/map/map.directive.html', 
      scope: { 
       deals: '=', 
       branches: '=' 
      }, 
      restrict: 'EA' 
     }; 
     return directive; 

     function link(scope, element, attrs) { 
      var script = document.createElement('script'); 
      script.type = 'text/javascript'; 
      script.async = true; 
      script.defer = true; 
      script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyB4RaOArTNm9C7crfutMVc0KkWIoQG-ZE0"; 
      document.body.appendChild(script); 

      $timeout(function(){ 
       scope.initialize(); 

      }, 500); 

      // todo: Do stuff after deals are loaded based on map radius 
      scope.$on('branchesSorted', function(event, data) { 
       console.log('deals loaded'); 
       console.log(data); 
       var points = mapApi.geocode(data); 
       console.log(points); 
      }); 

      scope.initialize = function() { 

       scope.mapOptions = { 

        zoom: 8, 
        center: new google.maps.LatLng(22.649907498685803, 88.36255413913727) 
       }; 
       scope.map = new google.maps.Map(document.getElementById('map'), scope.mapOptions); 

      }; 

      console.log(scope); 
     } 
    } 
})(); 
+0

私は角に非常に良いではないですが、APIが完全に充電されたと私は任意のものの魔女があなたのコードでは、この意味で行くのを見ていない後、通常、あなたのマップを初期化する必要があります。 –

答えて

0

このエラーは、Google Maps APIがまだ読み込まれていないために発生します。

データがロードされつつある瞬間:

scope.$on('branchesSorted', function(event, data) { 
      console.log('deals loaded'); 
      console.log(data); 
      var points = mapApi.geocode(data); //<--Google Maps API could be still not loaded at that moment 
      console.log(points); 
     }); 

$http.get('app/cwitsTestData/branchData.json').then(function(data){ 
     vm.branches = sortBranches(data.data.branches); 
     $scope.$broadcast("branchesSorted", vm.branches); 
}); 

、その後一度Geocoderが利用され、Google MapsのAPIがすでにその時点でロードされていることをなしいかなる保証するものではありGoogleマップのライブラリから

は、このようなあなたの例では、非同期を読み込まなっている。

var script = document.createElement('script'); 
script.type = 'text/javascript'; 
script.async = true; 
script.defer = true; 
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyB4RaOArTNm9C7crfutMVc0KkWIoQG-ZE0"; 
document.body.appendChild(script); 

代わりに次の解決策を提案します。

のは、GoogleマップAPIをロードマップを作成し、それが作成されると通知するために、以下のサービスをご紹介しましょう:

.factory('googleMapsApi', function ($rootScope,$window, $q) { 
    return { 
     load: function (key) { 
      var deferred = $q.defer() 

      if ($window.google && $window.google.maps) { 
       deferred.resolve($window.google); 
      } 
      else { 
        var url = 'https://maps.googleapis.com/maps/api/js?callback=googleMapsLoad'; 
        if (key) url += "&key=" + key; 
        var script = document.createElement('script'); 
        script.type = 'text/javascript' 
        script.src = url; 
        $window.googleMapsLoad = function() { 
         deferred.resolve($window.google); 
        } 
        document.body.appendChild(script); 
      } 
      return deferred.promise; 
     }, 
     createMap : function(scope,id,options){ 
      var mapObject = new google.maps.Map(document.getElementById(id), options); 
      scope.$emit('google-maps-loaded',mapObject); 
     }, 
     onMapReady : function(scope, ready){ 
      var handler = $rootScope.$on('google-maps-loaded', function(evnt,data){ return ready(data);}); 
      scope.$on('$destroy', handler); 
     } 
    } 
}) 

その後マップはディレクティブlink機能を経由して、次のように作成することができます。

link: function (scope, element, attributes) { 
      googleMapsApi.load(scope.key) 
      .then(function() { 
       var mapOptions = { 
        center: scope.center, 
        zoom: scope.zoom, 
        mapTypeId: google.maps.MapTypeId.ROADMAP 
       }; 
       googleMapsApi.createMap(scope,attributes.id,mapOptions); 
      }); 
     } 

そしてデータは、このようなコントローラにロードされる:

.controller('MyCtrl', function ($scope, googleMapsApi) { 

    googleMapsApi.onMapReady($scope, function(mapInst) { 
     console.log('Google Map is ready'); 
     mapInst.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/google.json'); 
    }); 
}); 

JSFiddle example

関連する問題

 関連する問題