Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to generate a map using the Angular-Leaflet-Directive and data from 2 different Angular services that call web services using $resource. These services return JSON messages that include lat/long values to populate markers on a map.

However, I cannot get the directive to use the data from the services.

I can see that my services are updating the scope so they are working OK, and the map markers render correctly if I hard code the values into the controller (for example, see "center" below). What I want to do is very similar to this example

Here is my code:

Controller:

angular.module('myDetails', ['leaflet-directive', 'shop', 'home'])
.controller('MyDetailsCtrl', ['$scope', '$routeParams', '$http', '$q', '$rootScope', 'shopService', 'homeService', function ($scope, $routeParams, $http, $q, $rootScope, shopService, homeService) {

        function getShop() {
        var d = $q.defer();
        var shop = shopService.get({shopId: $routeParams.shopId}, function (shop) {
            d.resolve(shop);
        });
        return d.promise;
    }

        function getHome() {
        var d = $q.defer();
        var home = homeService.get({homeId: $routeParams.homeId}, function (home) {
            d.resolve(home);
        });
        return d.promise;
    } 

$q.all([
            getShop(),
            getHome()
        ]).then(function (data) {
            var shop = $scope.shop = data[0];
            var home = $scope.home = data[1];

            var markers = {
                shop: {
                    lat: $scope.shop.loc.coordinates[0],
                    lng: $scope.shop.loc.coordinates[1],
                    draggable: false,
                    message: $scope.shop.name,
                    focus: true
                },
                home: {
                    lat: $scope.home.loc.coordinates[0],
                    lng: $scope.home.loc.coordinates[1],
                    draggable: false,
                    message: $scope.home.name,
                    focus: true
                }
            };
            console.log("Markers are " + angular.toJson(markers));
            $scope.markers = markers;
        });

    $scope.center = {
                lat: 53.26,
                lng: -2.45,
                zoom: 6
            };

}]);

What I find is that my 2 services return, scope is updated with the values, but this is not passed through to the angular-leaflet-directive.

The Angular documentation on directives suggests that the following code in a directive will link the child scopes to the parent scope so that they are both updated:

    scope: {
        center: '=center',
        maxBounds: '=maxbounds',
        bounds: '=bounds',
        marker: '=marker',
        markers: '=markers',
        defaults: '=defaults',
        paths: '=paths',
        tiles: '=tiles',
        events: '=events'
    }

but it does not seem to work for me. However, the angular-leaflet-directive path example does seem to allow this (you can add markers, change markers, etc.) and the map updates in real time.

What do I need to do to make the markers appear on my map once the services have returned?

Note that there are similar question on Stackoverflow for this, but the answer to these questions is to include the service calls within the Directive. I don't want to do this as the controller is offering more functionality than just a straight service call, such as handling form submission, etc. and requires access to the same data.

share|improve this question
add comment

2 Answers

Seems the easiest way to fix this is to ensure that you add the following lines to the controller...

angular.extend($scope, {
    markers : {}
}

This sets up the scope inheritance. I wasn't doing this before, so the scope in the leaflet directive was not aware of $scope.markers as it didn't exist!

share|improve this answer
add comment

I had a similar issue. In my case, I have a div tied to a controller wrapping the leaflet tag element:

<div ng-controller="MapCtrl">
    <leaflet id="map" class="map" maxBounds="maxBounds" defaults="defaults" center="center"></leaflet>
</div>

As you can imagine, the values for "maxBounds", "defaults", and "center" were in the parent $scope, not the $scope of the directive. To mitigate this, I had to modify the angular-leaflet-directive code to look up the scope stack for these variables:

var mapScope = $scope;
if (mapScope.defaults === null || typeof mapScope.defaults === "undefined") {
    mapScope = mapScope.$parent;
}
if (mapScope.defaults === null || typeof mapScope.defaults === "undefined") {
    throw new Error("Cannot find map defaults - have they been initialized?");
}

I admit that I'm new to Angular, so there may be a better way to accomplish this, but it worked for me.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.