Search code examples
angularjsangularjs-google-maps

ng-map: Initializing Map in Partial View


I'm trying to use the ng-map library in a partial view. It works fine on the initial setup of the page (i.e., when the partial view is first created).

But if I navigate away to a different partial view (say, by clicking a marker I've put on the map) and then hit the browser back button, things break down.

The map object appears to exist in $scope, but it's not "hooked up" to the element. So, for example, calling $scope.map.getBounds() results in a null value being returned.

The same is true if you call getBounds() on the map variable passed in to the mapInitialized event handler.

Eliminating the call to getBounds() -- which I use to pull in information to create markers -- eliminates the undefined value error. But the map itself is never initialized. The viewport is just a big, gray rectangle. I think this is further evidence that somehow the map html element is not being "hooked up" to the library code on re-creation of the partial view.

app.controller("mapCtrl", function ($scope, $location, dataContext) {
    $scope.markers = [];

    // these bind to attributes of the map element in my html
    $scope.pins = function() { return dataContext.pins(); }
    $scope.center = dataContext.center();
    $scope.zoom = function() { return dataContext.zoom() };

    $scope.$on('mapInitialized', function(evt, map){
        // this stores changes to the center of the map
        // so I can recreate it when the partial view is recreated
        $scope.dragend = function() {
            dataContext.center(map.getCenter());

            dataContext.get(map.getBounds());
        }

        // this stores changes to the map's zoom level
        // so I can recreate it when the partial view is recreated
        $scope.zoomchanged = function() {
            dataContext.center(map.getZoom());

            dataContext.get(map.getBounds());
        }

        // this is where I noticed the problem -- when
        // the partial view is initially created bounds is
        // defined and my marker creation routine works fine.
        // but when the view is recreated upon navigating back
        // to the partial view, bounds is undefined, and the
        // map never displays
        var bounds = map.getBounds();
        if( bounds != null ) dataContext.get(map.getBounds());
    });

    // this is the marker click handler, which takes us to a
    // different partial view
    $scope.click = function() {
        dataContext.pin(this.pinindex);

        if( dataContext.pin().Homes.length == 1)
        {
            dataContext.home(0);
            $location.path("/home");
        }
        else $location.path("/unit");
    };
});

Stepping through Map directive initialization

When the map directive is first executed (i.e., on initial page load), the attrs object passed to the initialization from angular contains a valid center and zoom.

But when the directive is subsequently initialized on a return to the page (i.e., when the partial view is recreated), only the zoom is defined properly. The center is " , ", which is meaningless.

I'm not sure why the center attribute value is being ignored the second time, but that seems to be the source of the problem. Unfortunately, attrs gets set inside the angular library, which I don't have time to explore. Hope this helps.


Solution

  • Turns out the problem was because I'd created my own latitude longitude object in a service to store the map center:

    var _center = { lat: ..., lng: ... };
    

    But was assigning a Google Maps LatLng object to it in a drag event handler:

    $scope.dataContext.center($scope.map.getCenter());
    

    Needless to say, this resulted in some undefined object attributes :). Apologies for wasting your time, Allen!