Take a look at the following plunker: http://plnkr.co/edit/uEbEdNifuBReENxzhb6H?p=preview
The expected behaviour for the routeProvider resolve (to my understanding) is for the resolved object to be injected into the controller. However Angularjs throws an "Unknown provider" error.
I have seen suggestions to inject the original service, but that will result in a deferred object, which renders the routeProvider resolve rather useless.
You should specify the controller with the root provider - not in the template (or the controller will be used regardless of the path, which may result in the dependencies not resolving):
$routeProvider.when('/',{controller:'TestCtrl', ...
I've updated your plunker: http://plnkr.co/edit/mSb58e8cGDNYU27xSizk?p=preview
Related
I do understand why angular throws this error but i didn't find a solution that solves my case.
When angular encounter with ng-controller attribute, it tries to find injected controller named as the attribute value.
For example for my case:
Angular tries to find StreamHelperController in the injected controller list, when it doesn not find it, it throws
"StreamHelperController is not a function"
.
Known Solution: Injecting controller before loading view layer.
Controller:
var app = angular.module('myapp');
app.controller('StreamHelperController', ['$scope', function ($scope) {}]);
View:
<div ng-controller="StreamHelperController ">
But the problem occurs when i load view before controller class. And this is my case. So how can i manage and solve this problem ?
ENV:
Angularjs 1.5.8
javascript is synchronous.
controller is the bond|connection between model and view, without it no communication.
Thus, controller not defined at time will freeze the parsing.Try using promise or some other asynchronous trick or provide more info.
I am registering a controller on the state object by giving it a function. However the controller depends on things like $scope,$rootScope, and a couple of other services. How can I make the notation work if I am passing it a function? The solution should also work if the code is minified.
Here is my code
var mod = angular.module('myApp',['ui.router']);
mod.config(['$urlRouterProvider','$stateProvider',function(u,$stateP){
$stateP.state('myState',{
controller : controllerFunction //this is the controller that has dependencies.
})
}]);
As a side note -- I know there exist a resolve property that can be used to pass dependencies, but how can I pass $scope when it isn't defined, etc.
Even though the documentation states otherwise (look at the controller property) the controller property will happily take an inline array of dependencies with the controller function being the last index like so.
{
controller : ['$scope','$http',...,controllerFunction];
}
I have a route definition as follows:
.state('user_login', {
url: '/user/login',
templateUrl: 'login.tpl.html',
controller: 'AuthenticationCtrl',
resolve: {
practice: ['$q', function($q) {
return $q.when({});
}]
}
})
Things work as expected when I inject "practice" into the controller. When I use the $injector, service however:
$injector.get('practice')
I get an unknown provider exception. Are resolve objects not available to the $injector? How I can expose them in the controller without explicitly injecting them in the controller definition?
Note: I am using Angular 1.2.x
No, you cannot get them separately via $injector. And you cannot even inject them separately as well in other places, say the same controller (AuthenticationCtrl) instantiated by ng-controller directive.
Resolve objects are not any service or any other entity which can be injected separately. It is a special dependency injected by the router when the controller AuthenticationCtrl is bound via the router. You cannot get the instances separately. Only router knows about the resolve properties and while the router instantiates the controller (once all the resolve dependencies are resolved) it looks for resolve properties in the annotation (of the dependency list specified via explicit/implicit dependency annotation in the definision of AuthenticationCtrl) of the route-bound controller and injects them as required.
This kind of special implementation can be found in other components as well like, angular-ui-modal, ui-state-router, angular-router's routeprovider etc..
I need to inject an extra object to my controllers dynamically so I thought it'd be best to do it in the run function like so:
angular.module("app").run([
"$rootScope", "$inject", "repository.user", function ($rootScope, userRepository) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
var controller = next.$$route.controller;
userRepository.getSession(function(data) {
// What do do now?
});
});
}
]);
I'd like to inject that returned data into my controllers but I'm not sure how to do it?
Take a look at the $routeProvider documentation, specifically the resolve configuration option for a route. Have you thought about using this to dynamically resolve your dependency?
resolve - {Object.=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. The map object is:
key – {string}: a name of a dependency to be injected into the controller.
factory - {string|function}: If string then it is an alias for a service. Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before its value is injected into the controller. Be aware that ngRoute.$routeParams will still refer to the previous route within these resolve functions. Use $route.current.params to access the new route parameters, instead.
If I understand correctly, you are trying to collect user login state for every route change. Why not just save the data in $rootScope as something like $rootScope.currentUser = data.
This way you can access $rootScope.currentUser from any controller.
I have a bit of a problem with an Angular application. Basically I want to manipulate the scope outside of the application itself. If I type in the console:
$scope = angular.element($('.lead-system')).scope()
I can use $scope with $apply and it all works fine. However, when I use this in a rails coffeescript file:
angular.element(document).ready ->
console.log angular.element($('.lead-system')).scope()
It logs undefined and of course I can't use $apply with that.
What's up with that? I'm loading the JS files in this order:
app.js <-- Main angular app initializer
pending.js.coffee <-- The file listed above
lead_controller.js <-- The controller of the scope I'm trying to access
Wrap it in the $timeout, just to check if it will work then. That should tell you if this can be fixed by different timing or give you ideas for further exploration.
My recommendation though would be to fire an event (emit/broadcast or even arbitrary external thing in your case) in controller and in reponse to that event manipulate the scope. You could even pass the scope as parameter for convenience.