1

I'm trying to implement a google place search in Angular but the search result list is not updating when the callback happens. It only updates the $scope variable after the function setting the variable runs twice?? The variable that is not updating is $scope.fullCtrl.searchResults

HTML:

<body ng-app="myApp" ng-controller="fullCtrl">
  <div class="row">
    <div class="col-sm-12 col-xs-12">
      <div id="map-canvas"></div>
      <p>{{ fullCtrl.searchResults }}</p> <!-- not updating -->

      <!-- click twice and it updates -->
      <button ng-click="searchPlaces()">Search</button> 
    </div>
  </div>
</body>

myApp.js

myApp.factory('getWait', function ($http, $q) {
  return {
   getUrl: function(url, data) {
     var deferred = $q.defer();
     $http.get(url, data)
       .success(function(rtn) {
          deferred.resolve({
            res: rtn
          });
       }).error(function(msg, code) {
          deferred.reject(msg);
       });
     return deferred.promise;
   }
  }
});


myApp.controller("fullCtrl", ['$scope', '$http', "$window", "getWait",
                     function ($scope,   $http,   $window,   getWait) {
  $scope.fullCtrl = {};  

  $scope.fullCtrl.userLOCip = [];
  $scope.fullCtrl.searchResults = []; //declared here!
  var infoWindow = new google.maps.InfoWindow();
  var service;
  var searchLoc;
  getWait.getUrl('http://ipinfo.io/json').then(
    function(data) {
      $scope.fullCtrl.userLOCip = data.res.loc.split(',');
      $scope.fullCtrl.userLOCip[0] = Number($scope.fullCtrl.userLOCip[0]);
      $scope.fullCtrl.userLOCip[1] = Number($scope.fullCtrl.userLOCip[1]);
      console.log($scope.fullCtrl.userLOCip);

      // Google maps
      var mapOptions = {
        zoom: 10,
        center: new google.maps.LatLng($scope.fullCtrl.userLOCip[0], $scope.fullCtrl.userLOCip[1]),
      }

      $scope.map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      service = new google.maps.places.PlacesService($scope.map);
      searchLoc = new google.maps.LatLng($scope.fullCtrl.userLOCip[0],
                                             $scope.fullCtrl.userLOCip[1]);

    }
  );

  $scope.searchPlaces = function () {
    var request = {
      location: searchLoc,
      radius: 8047, // 5 miles
      types: ['store']
    };
    service.nearbySearch(request, callback);
  }

  var callback = function (results, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        $scope.fullCtrl.searchResults.push(results[i].name); // UPDATED HERE!
        createMarker(results[i]);
        console.log(results[i].name);
      }
    }
  }

  var createMarker = function (place) {
    var marker = new google.maps.Marker({
      map: $scope.map,
      position: place.geometry.location,
      title: place.name
    });

    google.maps.event.addListener(marker, 'click', function() {
      infoWindow.setContent(place.name);
      infoWindow.open($scope.map, marker);
    });
  }

}]);
Zanon
  • 29,231
  • 20
  • 113
  • 126
Elementary
  • 399
  • 2
  • 5
  • 17
  • 6
    You need $scope.$apply() because the callback is triggered by the google maps client that Angular doesn't know about. – Anthony Chu Jul 25 '14 at 21:48

1 Answers1

1

You need $scope.$apply() because the callback is triggered by the google maps client that Angular doesn't know about.

Turning this comment into an answer to make it easier to see. More info about $apply() here, here and here.

Community
  • 1
  • 1
Zanon
  • 29,231
  • 20
  • 113
  • 126