0

I am loading a Google map and when I navigate to /map it loads the the markers to populate the map. The problem is that the rest of the javascript runs and executes before the markers have loaded. What I thought would solve it would be to return a promise in the factory that retrieves the map data. This didn't work though.

Can anyone advise on what I'm doing wrong?

In the console I see this:

angular.js:13920 TypeError: Cannot read property 'lat' of undefined
at Object.link (http://localhost/logintest/js/app.js:586:55)

Line 586 refers to this line (in the directive):

            center: new google.maps.LatLng(lastElement.lat, lastElement.lon),

I get the lastElement like so:

var lastElement = scope.arrLocations[scope.arrLocations.length - 1];

Factory:

app.factory('map', ['$q', function($q){

var map={};
var mapInfoItems=[];

map.getMapInfo = function() {
    var deferred = $q.defer();
    var mapitems = firebase.database().ref('mapinfo/'+firebase.auth().currentUser.uid);
    mapitems.on('child_added', function(snapshot){
        mapInfoItems.push(snapshot.val());
        deferred.resolve(mapInfoItems);
    });

    return deferred.promise;
};

    return map;
}]);

Controller:

app.controller('mapController', ['$scope', 'map', function($scope, map){
    $scope.myLocations = {};
    $scope.arrLocations = [];
    $scope.mapLocations = map.getMapInfo();

    for(var i=0; i<$scope.mapLocations.length; i++){
        $scope.myLocations.title   = $scope.mapLocations[i].name;
        $scope.myLocations.content = $scope.mapLocations[i].message;  
        $scope.myLocations.lat     = $scope.mapLocations[i].lat;
        $scope.myLocations.lon     = $scope.mapLocations[i].lon;
        $scope.arrLocations.push($scope.myLocations);
    }

}]);

html:

<div ng-controller="mapController">
    <my-map get-map-fn="getMap()"></my-map>
</div>
3
  • What does the console say? Commented Oct 8, 2016 at 0:13
  • I've added a bit more detail. Commented Oct 8, 2016 at 0:21
  • OK so something is wrong with the creation of arrLocations. Let's log the prior step in the console and see what it looks like. Maybe console.log($scope.myLocations); Commented Oct 8, 2016 at 0:27

1 Answer 1

1

map.getMapInfo() returns a promise but you are treating it as if it returns an array in the controller

Also you keep overwriting the properties of the same object in your for loop and pushing the same object reference into an array. This means all elements in the array will end up with the last value set in the loop...because they are all references to one object

Replace

$scope.mapLocations = map.getMapInfo();

With

map.getMapInfo().then(function(locations){
   for(var i=0; i<locations.length; i++){
        // create new object each iteration
        var obj ={
           title  : locations[i].name,
           content: locations[i].message,
           // ... etc    
        }     

        $scope.arrLocations.push(obj);
    }    
});
Sign up to request clarification or add additional context in comments.

1 Comment

That makes perfect sense to me, looks like it should work. I'm having a look at it just now but I'll probably need to come back to it later, as its 2am here. Thank you :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.