I have been using oclazyload to reduce response time. While loading the homeController I can see that it has been loaded in network tab through oclazyload. But the controller is not triggered whie calling the html page. I am getting error like :
Error: [ng:areq] http://errors.angularjs.org/1.3.12/ng/areq?p0=homeController&p1=not%20aNaNunction%2C%20got%20undefined
my Routes config :
$routeProvider.when('/',
{
templateUrl: 'app/components/home/home.html',
controller: 'homeController',
resolve:
{ // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load('app/components/home/homeController.js');}]}});
How can I resolve this?
Related
I have a couple of modules that I am trying to load at runtime based on some conditions. Currently I am using theocLazyLoad module but I am the loaded module's are not working at all. Everything loads fine, there are no errors being thrown.
I first declare my main module
var app = angular.module('myApp',['oc.lazyLoad'])
app.config(['$ocLazyLoadProvider',function(){
modules : [{
name : 'mod1',
files : [CDN-Path]
}]
}]);
and then somewhere in my controller
app.controller('c',function($ocLazyLoad){
$ocLazyLoad.load('mod1').then(function(){
console.log('module loaded!');
});
})
What I truly do inside the resolved promise is that I register a new state with ui-router, and within that state I use some of the directives defined in mod1, but they simply don't work. Is there further initialization that must be performed after the module loads?
You can lazy load any module/directive/controller/javascript(jquery as well) before view as below:
angular.module('app', ['ui.router', 'oc.lazyLoad']).config(['$stateProvider', '$ocLazyLoadProvider', function ($stateProvider, $ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
modules : [{
name : 'TestModule',
files : ['js/TestModule.js', 'js/AppCtrl.js']
}
]
});
$stateProvider.state('index', {
url : "/", // root route
views : {
"lazyLoadView" : {
controller : 'AppCtrl', // This view will use AppCtrl loaded below in the resolve
templateUrl : 'partials/main.html'
}
},
resolve : { // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl : ['$ocLazyLoad', function ($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load('TestModule');
}
]
}
});
}
]);
https://oclazyload.readme.io/docs/with-your-router
Edit Plunker sample with controller and ui-bootstrap lazy loaded : https://plnkr.co/edit/pUq3b1TDkwdGQOftcWDL?p=preview
I'm not sure what I'm doing wrong. I'm getting this error
Error: [$injector:unpr] http://errors.angularjs.org/1.2.21/$injector/unpr?p0=propertyUserDataProvider%20%3C-%20propertyUserData
at Error (native)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:6:450
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:36:145
at Object.c [as get] (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:34:236)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:36:213
at c (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:34:236)
at d (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:34:453)
at Object.instantiate (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:35:103)
at $get (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:67:253)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js:53:362 <div ui-view="performance-ui-view" class="ng-scope">
Here is my code:
// the controller
app.controller('GlobalDashboardController', ['propertyUserData', function(propertyUserData) {
}])
// ui-router snippet
.state("main", {
url: "/",
views: {
'' : { templateUrl: 'views/main.html' },
'performance-ui-view#main': {
templateUrl: 'views/gdreport.html',
controller : 'GlobalDashboardController',
resolve: {
propertyUserData : function() {
return 'test';
}
}
}
}
})
Right now, I'm returning the string 'test' so I can debug. I do have a User service which I will use once the error is fixed. However, I'm really confused as to why it's failing. Once I remove resolve and the dependency injection in the controller, my application starts working fine again.
You should remove ng-controller directive from your partial view gdreport.html since you have specified the controller in the route itself, it will instantiate and bind the controller to the partial view. And you cannot instantiate this controller yourself because of the dynamic dependency provided via resolve property can only be injected by the router. And your error reflects exactly what it means, i.e propertyUserData provider does not exist.
I have a AngularJS application and have a requirement to initialize data from a REST API before the controller initializes. I use the "resolve" in the routeProvider and also injected the relevant value in the controller in order to make this data available. The code snippets are as follows:
RouteProvider code snippet:
myApp.config(function($routeProvider) {
$routeProvider
....
.when('/account', {
templateUrl : path + 'admin/js/pages/inputs/account.html',
controller : 'mainController',
resolve: {
data: function() {
return $http.get(api_path + 'dashboard/get_accounts');
}
}
})
myApp.controller('mainController', function($scope,$http, data, $routeParams, DataService) {
...
console.log(data);
}
The console is supposed display the data by I get the following error " Error: [$injector:unpr] Unknown provider: dataProvider <- data "
Your help much appreciated.
It's because the data provider has not instantiated yet and it is instantiating the controller before the provider is ready, coming through as an undefined and unknown provider.
Try something like this that returns a promise:
myApp.config(function($routeProvider, $q) {
$routeProvider, $q
....
.when('/account', {
templateUrl : path + 'admin/js/pages/inputs/account.html',
controller : 'mainController',
resolve: {
data: function() {
return $q.all($http.get(api_path + 'dashboard/get_accounts'));
}
}
})
Now, the controller won't instantiate until the promise has resolved completely. As per the documentation for $routeProvider and how it handles promises in the resolve.
$routeProvider on Angular's website
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.
Setup
I have a directive that takes a path to a json file as attribute value, loads the json, then instantiates Swiffy:
angular.module('myApp')
.directive('swiffy', function ($http) {
return {
restrict: 'A',
scope: {},
link: function postLink($scope, $element, attrs) {
var stage;
// Listen to angular destroy
$scope.$on('$destroy', function() {
if(stage) {
stage.destroy();
stage = null;
}
});
// Load swiffy json
$http({
method: 'GET',
url: attrs.swiffy
}).success(function(data, status, headers, config) {
stage = new swiffy.Stage( $element[0], data );
stage.start();
}).error(function(data, status, headers, config) {
});
}
};
});
The markup:
<div swiffy="my-animation.json"></div>
I also have a basic routing setup:
angular
.module('myApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/info', {
templateUrl: 'views/info.html',
controller: 'InfoCtrl'
})
.otherwise({
redirectTo: '/'
});
});
The controllers here are empty.
Problem
The json file loads as it should and the Swiffy svg is created just fine. But when i navigate away from a view that has a swiffy directive, angular throws an error and the whole app breaks:
TypeError: Cannot read property '1' of null
at annotate (angular.js:3179:24)
at Object.invoke (angular.js:3846:21)
at angular.js:5580:43
at Array.forEach (native)
at forEach (angular.js:323:11)
at Object.<anonymous> (angular.js:5578:13)
at Object.invoke (angular.js:3869:17)
at angular.js:3711:37
at Object.getService [as get] (angular.js:3832:39)
at addDirective (angular.js:6631:51)
The error is thrown after the '$destroy' event has triggered in the directive, so i know that stage.destroy() has run on the Swiffy object.
The angularjs function that throws the error can be found here https://github.com/angular/bower-angular/blob/7ae38b4a0cfced157e3486a0d6e2d299601723bb/angular.js#L3179
As far as i can tell, annotate() is trying to read the parameters on an anonymous function and fails. I have no errors if i remove the Swiffy instantiation so the errors have to be a result of creating the Swiffy object.
I'm using:
AngularJS 1.2.16
Swiffy runtime version 6.0.2
So far I've tried:
updating to AngularJS version 1.2.17-build.111+sha.19d7a12. (It contains an update to the annotate function but that doesn't fix the problem)
removed 'strict mode' from directive.
removed stage.destroy()
I'd rather not make any changes to the angular.js source (I tried to make angular skip anonymous functions but that broke even more things) and the swiffy runtime is not available un-minified so i'm not sure what is going on in there. Any ideas would be great, thanks.
TLDR: I can't get the resolve function in the base state to work and get my named views to display the right thing.
I've got a set of working routes with named views (docs here) that look like this:
$stateProvider.state("index",
url: ""
views:
viewA:
templateUrl: "/partials/index.A.jade"
controller: ($scope) ->
console.log('index controller') # just confirming that I'm hitting this line
viewB:
templateUrl: "/partials/index.B.jade"
)
... etc, 5+ states
I need to add in a resolve to load lodash via a promise:
resolve: util: ($q, $window) ->
console.log 'resolving base state'
deferred = $q.defer()
require(["cdn-lodash"], (lodash) ->
util = lib: lodash, logger: $window.logger
deferred.resolve(util)
)
deferred.promise
If I attach this resolve to the index state it works fine. But I need lodash in many states so I'd rather just load it for all states (alternately I could call this base "util" and add it in as a base for the states that need it:
$stateProvider.state('base',
abstract: true
resolve: util: ($q, $window) ->
console.log 'resolving base state'
deferred = $q.defer()
require(["cdn-lodash"], (lodash) ->
util = lib: lodash, logger: $window.logger
deferred.resolve(util)
)
deferred.promise
)
$stateProvider.state("base.index",
url: ""
views:
viewA:
templateUrl: "/partials/index.A.jade"
controller: ($scope, util) ->
debugger
console.log('index controller')
console.log util
$scope.allowAdmin = true
viewB:
templateUrl: "/partials/index.B.jade"
Well that doesn't work because none of my named views are loading, I just get a blank page. The resolve is being hit though. The page loads fine with no errors and the page headers etc in layout.jade are loading. So I tried adding the A/B views to the base state:
views:
viewA: templateUrl: ''
viewB: templateUrl: ''
Crud, now the views are loading, but not correctly. The A view is in the markup twice while the B view (which is empty on the index page) is not there at all. In the short term I think I can fix this by making a resolve function outside of the state declaration and putting it in the resolve for each state.
Also one other complication: most of my controllers are declared in their own files so the views line looks like:
views:
viewA:
controller: 'adminUserList' # <<<<<<<--------- this line
templateUrl: "/partials/admin/user/list.A.jade"
viewB:
templateUrl: "/partials/admin/user/list.B.jade")