0

In the .run section of the main module of my application, I have an event handler for the $locationChangeStart event. I want to use this in order to confirm discarding unsaved changes. The problem is that I need a reference to the $scope in order to perform these checks.

I tried adding that reference as I added the one for the $rootScope, but I get an error Uncaught Error: Unknown provider: $scopeProvider <- $scope.

How should I proceed to this? I am open for alternatives.

.run(['$rootScope', '$location', function ($rootScope, $location) {
    $rootScope.$on("$locationChangeStart", function (event, next, current) {
        if ($scope.unsavedChanges && !confirm('Unsaved changes') {
            event.preventDefault();
        }
    });
 }
Adrian Marinica
  • 2,191
  • 5
  • 29
  • 53
  • Run block runs like a main method before any other controllers execute. How can you inject dependency which you yourself would determine in the future. Injections happen at construction time so the dependency should be available to inject. – Chandermani Aug 30 '13 at 12:10
  • You're saying I should use $inject? – Adrian Marinica Aug 30 '13 at 12:18
  • Why not use a factory/service? – noj Aug 30 '13 at 13:13
  • AdrianMar > He is saying you can't do it (like this at least). $scope is not available on the run method. You are not on a controller so the only scope you have access to is the rootScope, and you can't go from the rootScope to the children. – Erik Honn Aug 30 '13 at 14:20
  • Check http://stackoverflow.com/questions/13428042/angularjs-access-to-child-scope for some ideas about how to handle this. You probably can't use broadcast however, since you can't wait for a reply when doing preventDefault, but the others might hold water. – Erik Honn Aug 30 '13 at 14:31

2 Answers2

1

You can only inject instances (not Providers) into the run blocks. This is from the doc of module.

angular.module('myModule', []).
    run(function(injectables) { // instance-injector
        // This is an example of a run block.
        // You can have as many of these as you want.
        // You can only inject instances (not Providers)
        // into the run blocks
    });

So you won't be able to inject $scopeProvider.

zs2020
  • 53,766
  • 29
  • 154
  • 219
  • I ended up setting the `$locationChangeStart` event handler on the controllers where it is needed (directly on the `$scope`). It is a little bit of code duplication, but I can manage it. Thanks! – Adrian Marinica Aug 30 '13 at 14:43
0

You could inject $scope to your function like;

 .run(['$rootScope', '$location', '$scope', function ($rootScope, $location, $scope)
BKM
  • 6,949
  • 7
  • 30
  • 45
  • Thanks for trying to help, but I already tried this. I said it in the question. It gives an error: `Uncaught Error: Unknown provider: $scopeProvider <- $scope`. – Adrian Marinica Aug 30 '13 at 11:50
  • Why don't you use $rootScope instead of $scope here? – BKM Aug 30 '13 at 11:55
  • Because I don't want to pollute the `$rootScope` with information specific to some of the controllers. It's just a personal preference. – Adrian Marinica Aug 30 '13 at 11:57