Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

ScopeProvider error when injecting $scope into a controller when using v0.5 #192

Closed
ChrisPearce opened this issue Mar 18, 2015 · 11 comments
Closed
Milestone

Comments

@ChrisPearce
Copy link

I'm seeing a scope provider error with v0.5 of new Angular Router (n.b. it didn't seem to be present in v0.4).

The error message is:
[$injector:unpr] Unknown provider: $scopeProvider <- $scope <- TestController↵http://errors.angularjs.org/1.4.0-beta.6/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20TestController
n.b. This error is swallowed and displays only as a warning "Could not instantiate controller TestController" in the console.

I've created a Plunker that demonstrates the issue at http://plnkr.co/edit/dPaCCogHwNYjgvyvTP9R?p=preview.

The Error only occurs when $scope is injected into the Test Controller.
If I remove the $scope injection from the controller, I then see no errors.

@ulrikstrid
Copy link

This feels like a major bug, unless 1.4 plans to move $watch etc away from the $scope.

ggranum added a commit to ggranum/twisted-kindling that referenced this issue Mar 18, 2015
…reakage. Note that the use of $rootScope is a hack (maybe?) to deal with angular/router#192.
@btford
Copy link
Contributor

btford commented Mar 19, 2015

Yep, this is a bug. I'll look into it this afternoon.

@btford btford added this to the v0.5.1 milestone Mar 19, 2015
@robguthrie
Copy link

Just tried to adopt 0.5.0 and ran into this issue.

I really enjoy this router and want to say thanks for all your work, @btford. It's nice code to learn from.

I'm keen to hear when this is fixed or you have an update. Thanks again!

@robgrimball
Copy link

Just an added comment to try to help narrow this issue down. Commit a6166ff works fine for me, but commit b9321e6 shows up the same error as mentioned above with routeProvider not being found. Hope that helps!

@btford btford closed this as completed in 2136ca8 Mar 28, 2015
@btford
Copy link
Contributor

btford commented Mar 28, 2015

So it's a bit complicated to explain, but ctrl.activate is the right place to get ahold of $scope.

I'll update the Lifecycle docs with more on this soon.

@dotch
Copy link

dotch commented Mar 28, 2015

can you give us a quick example on how to access scope from ctrl.activate ?

@bisubus
Copy link

bisubus commented Apr 8, 2015

@btford Is it how it's going to be? Am I missing something?

var SomeController = ['$rootScope', function ($rootScope) {
    var $scope;

    this.activate = ['$scope', function (scope) {
        $scope = scope;
        this._init();
    }];

    this._init = function () {
        // all the $scope are belong to us
    };

}];

Yep, scope isn't a provider and does not deserve a mere injection, but I personally find it a bit too much. Unless it is being planned as a common behaviour for all 1.4 controllers, then sure, syntactic bitter all the way.

@robianmcd
Copy link

I just ran into this. Is it covered in the docs yet? I didn't see anything here https://angular.github.io/router/lifecycle but not sure if it's covered somewhere else. This could also use a more descriptive error message as it will probably come up a lot.

Other than this the new router has been working out great for me. Thanks @btford !

@wizardwerdna
Copy link

So two controllers cannot share a common state unless a single common controller is defined in the router, using the "components:" syntax? Fairly common in plural/detail scenarios.

/pluralthings
/singularthing/1

when there is a common list of things accessible to a controller. What is the best practice in this context.

@TomerAvni
Copy link

NEWER ANSWER

With the new router the controller gets initiated before the child scope is being created.

The child scope (the controller's scope) is created when the activate method is being called - that is - after the actual compilation of the view is finished. Therefore, it is simple impossible the inject $scope - it is simple created later.

Long story made short...
There is a better, built-in solution for this.


Instead of assigning your properties to the non-existing-yet $scope, simply assign them on the "this" variable - the controller instance variable. Then on the view, you can use them by referring the controller name:

angular.module('app.home').controller('HomeController', HomeController);

function HomeController() {
    this.name = "tomer";
}

And now on the template html:

<div>
    <h1>{{home.name}}
</div>

Makes sense?

@nnennajohn
Copy link

Hi. Yeah. It makes sense. But is there a way to access it in the view by directly writing name? Without the home prefix? I find this a bit much typing home. everything over and over again.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests