I have a question similar to this one, but different.
Here I am trying to add an event listener for a window.postMessage
handler.
app.run(function ($location, $window, $rootScope) { $window.addEventListener('message', function(e) { $location.path("/abc"); console.log($location.path()); // this prints "/abc" as expected $rootScope.$apply(); // this has no effect $scope = angular.element(document).scope(); // this is the same as $rootScope $scope.$apply(); // so this also has no effect }); });
The $location.path
isn't being recognised by Angular.
The other question says that I should call $apply()
on the scope, but the only scope available to me is $rootScope
and calling $apply()
on that doesn't seem to work.
A comment on the answer suggests that a scope can be got with
$scope = angular.element(document).scope()
but this gives me the $rootScope
, which doesn't work.
How do I get angular to regocnise the change in $location.path()
? Is there a better way to register a message
callback in such a way as I can change the path?
To change path URL with AngularJS, $location. path() is passed the new URL as a parameter, and the page is automatically reloaded. This means that if you ever make a change to the URL in an Angular application, then the partial and controller will be reloaded automatically.
In HTML5 mode, the $location service getters and setters interact with the browser URL address through the HTML5 history API. This allows for use of regular URL path and search segments, instead of their hashbang equivalents.
Overview. The $location service parses the URL in the browser address bar (based on the window. location) and makes the URL available to your application. Changes to the URL in the address bar are reflected into $location service and changes to $location are reflected into the browser address bar.
You should run the expression as function in the $apply()
method like
app.run(function ($location, $window, $rootScope) { $window.addEventListener('message', function(e) { $rootScope.$apply(function() { $location.path("/abc"); console.log($location.path()); }); }); });
See documentation - ng.$rootScope.Scope.
If you want to improve testability, use $console
instead of console
and inject that object as well.
The accepted solution is not the appropriate way to do it. Ideally you shouldn't need to interfere with the digest cycle (which $apply() does).
The best way according to me is calling $location.path() from the MainController. Use $emit - $on
to send it to the MainController and have a function call $location.path from there. It will redirect you flawlessly without having to interfere with the digest cycle. I hope this helps someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With