6

According to the developer guide I should be able to access the browser window from inside Angular expressions with $window.

Unlike JavaScript, where names default to global window properties, Angular expressions have to use $window to refer to the global window object. For example, if you want to call alert(), which is defined on window, in an expression you must use $window.alert().

However I can't seem to access $window from expressions evaluated with $scope.$eval. Here are some outputs I get when logging out to the console:

console.log($window);                   // the Window object as expected
console.log($scope.$eval('$window'));   // undefined
console.log($scope.$eval('1+1'));       // 2
console.log($scope.$eval('scopeVar'));  // 'abc'

The controller has $window as a dependency. I can access scope variables and other services from expressions but not $window, so $scope.$eval($window.alert()) doesn't work either.

What am I missing here?

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
tamacun
  • 421
  • 1
  • 4
  • 9
  • If you landed here from Angular 2+ land, a quick hack (if you already have a [template variable](https://angular.io/guide/template-reference-variables) `#someElem` lying around) would be to `someElem?.innerElement?.nativeElement?.ownerDocument.defaultView` (`?` for safety) - which resolves to the underlying `Window` – Janaka Bandara Dec 29 '20 at 07:25

1 Answers1

7

$scope.$eval evaluates against the $scope, so your evaluation will work only if you assign $window service to scope member:

$scope.$window = $window;  
console.log($scope.$eval('$window'));
Stewie
  • 60,366
  • 20
  • 146
  • 113
  • 2
    This answer is correct, but it seems newer versions of AngularJS (I'm on 1.2.4) doesn't allow accessing the window object from expressions due to security reasons and you get this [error](http://docs.angularjs.org/error/$parse:isecwindow?p0=$window.alert() if you try. Well, I can't say the documentation is very consistent then... I'll just wrap the alert call in a controller function and use that from expressions. – tamacun Jan 08 '14 at 14:58
  • Great, get out of my way, Angular! At this point you could just do `$scope.window = window;` yeah you'd lose mockability but honestly at this point I'm just glad to bypass Angular and mockability is not something we'd need very soon. – aross Oct 28 '19 at 16:45