5

I'm using ngMap in an angularjs app. I'm running into an error when I try to set the zoom on a map element. Here's the error message from the Chrome console:

 TypeError: Cannot read property 'apply' of undefined
    at Wk.eventFunc (ng-map.js:205)
    at Object.T.trigger (main.js:18)
    at kf (main.js:22)
    at Wk.N.set (main.js:21)
    at Wk.setZoom (main.js:29)
    at ng-map.js:1568
    at angular.js:6837
    at forEach (angular.js:323)
    at Object.$get.Attributes.$set (angular.js:6835)
    at interpolateFnWatchAction (angular.js:8157)

This is being triggered when the zoom attribute of my map element:

<map center="{{initCenter.lat}}, {{initCenter.lng}}" zoom="{{zoom}}" on-dragend="dragend()" on-zoom_changed="zoomchanged()">

is being bound to my angular controller:

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

    $scope.initCenter = dataContext.center();
    $scope.zoom = dataContext.zoom();

dataContext is a service that exposes various state variables in the app. I've also tried setting $scope.zoom through a function, with the same resulting error.

The error takes place on line 1568 of the ng-map.js file:

    var observeAndSet = function(attrs, attrName, object) {
  attrs.$observe(attrName, function(val) {
    if (val) {
      void 0;
      var setMethod = parser.camelCase('set-'+attrName);
      var optionValue = parser.toOptionValue(val, {key: attrName});
      void 0;
      if (object[setMethod]) { //if set method does exist
        /* if an location is being observed */
        if (attrName.match(/center|position/) && 
          typeof optionValue == 'string') {
          _this.getGeoLocation(optionValue).then(function(latlng) {
            object[setMethod](latlng);
          });
        } else { 
          // this is the line that causes the problem
          object[setMethod](optionValue);
        }
      }
    }
  });
};

In trying to trace through what's happening I followed the execution for setting center and for setting zoom (setting center doesn't cause a problem). Setting the center executes line 1568 and continues on its merry way.

Setting zoom (via the setZoom function) causes code at line 196 in ng-map.js to execute:

      var eventFunc = function(attrValue) {
    var matches = attrValue.match(/([^\(]+)\(([^\)]*)\)/);
    var funcName = matches[1];
    var argsStr = matches[2].replace(/event[ ,]*/,'');  //remove string 'event'

    var args = scope.$eval("["+argsStr+"]");
    return function(event) {
      function index(obj,i) {return obj[i];}
      var f = funcName.split('.').reduce(index, scope);
      // this next line causes an exception in google map main.js
      f.apply(this, [event].concat(args));
      scope.$apply();
    }
  }

Line 205 leads to the exception that results in the error inside google map's main.js file.

Any idea what's causing this? And how to solve it :)?

Possible Solution

Playing around with this a bit more I noticed that it isn't setting the zoom level per se which causes the problem. It's actually the result of the zoomchanged event firing >>after<< the zoom is changed.

The first time zoom is set on the map, line 204:

var f = funcName.split('.').reduce(index, scope);

evaluates to null. I'm not sure why that is, because I don't understand what that line is doing.

However, the future changes to zoom have that same line 204 resolving to a non-null value for f.

So, as a workaround, I bracketed lines 205 and 206 like this:

  if (f != null) {
      f.apply(this, [event].concat(args));
      scope.$apply();
  }

and the error went away.

allenhwkim
  • 27,270
  • 18
  • 89
  • 122
Mark Olbert
  • 6,584
  • 9
  • 35
  • 69

1 Answers1

0

I think this has the same problem with this issue, https://github.com/allenhwkim/angularjs-google-maps/issues/181

and it's resolved with the release of 1.7.7.

I used $timeout, instead of $apply.

allenhwkim
  • 27,270
  • 18
  • 89
  • 122