I am having some issues trying to use the Angular dependency injection with different modules. At the moment, I have the following. In my index.html, the files are loaded in the following order (end of <body> tag):
network.js
authentication.js
login.js
app.js
network.js
angular.module('services.network', [])
.factory('Network', ['$http', '$state', function ($http, $state) { ... }]);
authentication.js
angular.module('services.authentication', ['services.network'])
.factory('Authentication', ['$state', 'Network', function ($state, Network) { ... }]);
login.js
angular.module('controllers.login', [])
.controller('LoginCtrl', ['$scope', function ($scope) { ... }]);
app.js
var app = angular.module('parkmobi', [
'ngRoute',
'services.network',
'services.authentication',
'controllers.login'
]);
app.run(['$rootScope', function ($rootScope) {
$rootScope.$on('$viewContentLoaded', function () {
$(document).foundation('reflow');
});
}])
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
});
}]);
Up until this point, everything seems to be quite happy. Now, however, I want to use the Authentication service in the LoginCtrl, which I would have thought is done as follows:
login.js
angular.module('controllers.login', ['services.authentication'])
.controller('LoginCtrl', ['$scope', 'Authentication', function ($scope, Authentication) { ... }]);
However, this causes the following injection error:
Error: [$injector:unpr] http://errors.angularjs.org/1.3.15/$injector/unpr?p0=%24stateProvider%20%3C-%20%24state%20%3C-%20Authentication
R/<#http://localhost/testapp/vendor/angularjs/angular.min.js:6:417
Error came because you've injected $state provider in your Authentication factory, without having ui.router module in app.js parkmobi module.
It should use $route instead of $state as your are doing your route in angular-router.
angular.module('services.authentication', ['services.network'])
.factory('Authentication', ['$route', 'Network', function ($route, Network) { ... }]);
Or if you want to use ui-router then you need to use $stateProvider while registering states & ui.router module should be include in your app.
Related
I am trying to have a link in my page such as:
<a ng-href="#/Page/{{x.ID}}">{{x.ID}}</a>
Which succesfully gets to the angular controller but however the $routeparams are null when I am expecting to get the {{ x.ID }} back:
pageController.js
angular.module("myApp.Pages").controller("pageController", ['$scope', '$http', '$routeParams', function ($scope, $http, $routeParams) {
console.log($routeParams);
}]);
And am referencing the state in my $stateprovider such as (in appRouting.js):
$stateprovider.state('Page', {
url: '/Page/:userId',
templateUrl: 'App/Pages/page.html',
controller: 'pageController'
})
my app.js
angular.module("myApp", [
// User defined modules
'myApp.Pages', // Pages
'myApp.Core', // Core
// Angular modules
'ui.router', // state routing
'ngRoute', // angular routing
'LocalStorageModule', //local browser storage
'angularRangeSlider',
'ngFileUpload'
])
Any ideas?
$stateParams instead of $routeParams
I am trying to learn routing by adding routing to a specific page in my rails app using angular which will replace ajax. Below is the console error am getting.
Uncaught Error: [$injector:modulerr] Failed to instantiate module
testApp due to: TypeError: Cannot read property 'state' of undefined
This is how I defined.
app.js
app = angular.module("testApp", ['ui.router']);
app.config([
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('mylistings', {
url: '/mylistings',
templateUrl: '/views/mylistings.html',
controller: 'dashboardCtrl'
});
}
]);
app.controller('dashboardCtrl', function ($scope, $http, $stateParams) {
$scope.testing="testdata"
});
mylistings.html
{{testing}}
In this case http://localhost:3000/dashboard is the url I want routing. Could someone tell me what am doing wrong here.
Problem is with definition of config function.
If you use array app.config([]) that means that you write safe code for the dependencies prepared for minification. Syntax is:
app.config(['$arg1', '$arg2', function ($arg1, $arg2) {
}]);
So when code is minified you will get something like:
app.config(['$arg1', '$arg2',function(a,b) {}]);
In your example in app.js change config to following code if you want to write code safe for minification (if you are not using ng-annotate):
app = angular.module("testApp", ['ui.router']);
app.config(['$stateProvider','$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('mylistings', {
url: '/mylistings',
templateUrl: '/views/mylistings.html',
controller: 'dashboardCtrl'
});
}
]);
app.controller('dashboardCtrl', function ($scope, $http, $stateParams) {
$scope.testing="testdata"
});
or you can remove [] from config function :
app.config(function ($stateProvider, $urlRouterProvider) {
...
}):
I need to switch view in my angular js webapp.
In order to handle the routing, I am using the $stateProvider, as here:
.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', function ($httpProvider, $stateProvider, $urlRouterProvider) {
$stateProvider
.state('common', {
templateUrl: 'assets/html/template.html',
abstract: true,
})
.state('login', {
url: '/login',
parent: 'common',
templateUrl: 'app/models/authentication/views/login.html',
controller: 'LoginController'
})
.state('home', {
url: '/',
parent: 'common',
templateUrl: 'app/models/home/views/home.html',
controller: 'HomeController'
})
...
Inside my login controller, I am trying to switch the view (from Login to Home)
.controller('LoginController', ['$scope', '$rootScope', '$cookieStore', '$location', '$window', '$http',
function ($scope, $rootScope, $cookieStore, $location, $window, $http) {
$scope.login = function () {
loadHttp();
};
function loadHttp() {
var url = "http://myurl";
...
.then(function (response) {
$scope.$apply(function () {
$location.path('/home');
console.log("$location.path: " + $location.path);
});
});
}
But when I reach $location.path('/home'); I get this error:
Error: [$rootScope:inprog] http://errors.angularjs.org/1.4.8/$rootScope/inprog?p0=%24digest
at Error (native)
at http://localhost:3000/adminTool/assets/js/angular.min.js:6:416
at t (http://localhost:3000/adminTool/assets/js/angular.min.js:126:132)
at r.$apply (http://localhost:3000/adminTool/assets/js/angular.min.js:133:515)
at http://localhost:3000/adminTool/app/models/authentication/controllers.js:46:32
at http://localhost:3000/adminTool/assets/js/angular.min.js:119:129
at r.$eval (http://localhost:3000/adminTool/assets/js/angular.min.js:133:313)
at r.$digest (http://localhost:3000/adminTool/assets/js/angular.min.js:130:412)
at r.$apply (http://localhost:3000/adminTool/assets/js/angular.min.js:134:78)
at g (http://localhost:3000/adminTool/assets/js/angular.min.js:87:444)
What am I doing wrong? How to get rid of it and finally switch view?
I read to use $apply from SO
PS: I am very new to angular
The error you get is because of the $scope.$apply around the $location.path('/home') statement. Angular is already in a digest loop so triggering it again within that loop (by calling $apply) will give you this error. Removing the $scope.$apply will therefor probably fix your problem.
The reason the digest loop is already triggered is because you are probably using the $http service which uses a promise to return the value. Angular always triggers a digest when resolving this promise.
But aside from that you probaly want to use the $state service to move to another state instead of moving to another location using the $location service. $state.go('home') would probably be what you are looking for.
I think here is the problem $location.path('/home');
You don't have path /home you have state called home
so you need to go $location.path('/'); or inject $state and use method $state.go('home'), also you do not need to wrap it inside $apply
I am able to lazy load angularjs with the help of requirejs. But, how can I load modules that needs to be associated to the controller?
My example configuration in app.js looks like the following, loading all the providers and keeping a reference.
var app = angular.module('myApp', ['ui.router'])
var cacheProviders = {};
app.getProvider = function () {
return cacheProviders.$provide;
}
app.getCompileProvider = function () {
return cacheProviders.$compileProvider;
}
app.getControllerProvider = function () {
return cacheProviders.$controllerProvider;
}
app.getFilterProvider = function () {
return cacheProviders.$filterProvider;
}
app.config(['$stateProvider', '$urlRouterProvider', '$controllerProvider', '$compileProvider', '$filterProvider', '$provide',
function ($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
(function () {
cacheProviders.$controllerProvider = $controllerProvider;
cacheProviders.$compileProvider = $compileProvider;
cacheProviders.$filterProvider = $filterProvider;
cacheProviders.$provide = $provide;
})();
var lazyCtrlLoad = function (controllerName) {
return ["$q", function ($q) {
var deferred = $q.defer();
require([controllerName], function () {
deferred.resolve();
});
return deferred.promise;
}];
}
$stateProvider.state('main.view2b', {
url: '/view2b',
templateUrl: 'forms/empl/searchEmplForm.html',
controllerAs: 'srchC',
controller: 'searchEmplCtrl',
resolve: {
loadOtherCtrl: lazyCtrlLoad('searchEmplCtrl')
}
})
In my other module, I am trying to register controllers, load services..
define([
'angular', 'angularResource'
], function (angular) {
angular.module('myApp')
.getControllerProvider()
.register(ctrl, ...)
But, while loading service below, I need access to $resource which is part of ngResource module in angularResource.
angular.module('myApp')
.getProvider().service('deptService', ['$resource', function ($resource) {
return $resource('/dept/:dept', {dept: '#_dept'});
}])
How can I load ngResource while initalizing the javascript controllers/services lazily?
Take a look to AngularAMD here. It allows you to load controllers in the ui-router without using lazyload. This AngularAMD is used to integrate requireJs and Angular.
$stateProvider
.state('home', {
url: '',
views: {
'#': angularAmd.route({
templateUrl: 'ngApplication/application/shared/layouts/basic/basicTplView.html',
controllerUrl: 'ngApplication/application/shared/layouts/basic/basicTplCtrl.js',
controller: 'basicTplCtrl'
}),
'header#home': angularAmd.route({
templateUrl: 'ngApplication/application/shared/layouts/header/headerView.html',
controllerUrl: 'ngApplication/application/shared/layouts/header/headerCtrl.js',
controller: 'headerCtrl'
})
},
});
Also, you are using requirejs, you can load all the dependencies for an specific controller using the define syntax of requireJs. Let's say you want to create a loginCtroller in a separately file, and this controller depends on another angular service:
define(['app', 'transformRequestAsFormPostService'], function (app) {
app.controller('loginCtrl', ['$scope', '$rootScope', '$sce', '$http', '$state', 'transformRequestAsFormPostService', function ($scope, $rootScope, $sce, $http, $state, transformRequestAsFormPost) {
$scope.login = function () {
/*do something here using the service*/
};
}]);
});
Here, the dependency called transformRequestAsFormPostService is another file, I defined it in the main.js (requireJs confifguration file) and it's defined using the same approach than the loginCtrol. Now I am using it in my project and its working so far so good.
Regards,
Ernesto
It was working fine when I used the $http service, but I wanted to make it RESTful. I'm getting errors now. Can someone kick me in the right direction? What am I doing wrong?
app.js:
'use strict';
angular
.module('swoleincApp', [
'ngRoute',
'ngSanitize',
'ngAnimate',
'ngResource'
])
.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider
.when('/models', {
templateUrl: 'app/views/main.html',
controller: 'MainCtrl'
})
.when('/models/:modelId', {
templateUrl: 'app/views/individual.html',
controller: 'ProfileCtrl'
})
.otherwise({
redirectTo: '/models'
});
$locationProvider.html5Mode(true);
}]);
ProfileService.js:
'use strict';
angular
.module('swoleincApp')
.factory('Profile', ['$resource', ProfileService]);
function ProfileService($resource) {
return $resource('app/storage/individual/:modelId.json', {}, {
query: {
method: 'GET',
params: {
modelId: 'individual'
},
isArray: true
}
});
}
ProfileCtrl.js:
'use strict';
angular
.module('swoleincApp')
.controller('ProfileCtrl', ['$scope', ProfileCtrl]);
function ProfileCtrl($scope) {
$scope.profile = Profile.query();
}
When I load the models/:modelId page, the page loads respective to the modelId that was clicked but the angular doesn't compile or whatever, I just get brackets with strings in them.
I also get this error (note I am using Laravel with Homestead and VirtualBox):
ReferenceError: Profile is not defined
at new ProfileCtrl (http://laravel.app/app/js/controllers/ProfileCtrl.js:8:19)
at e (http://laravel.app/app/js/dependencies/angular.min.js:39:193)
at Object.instantiate (http://laravel.app/app/js/dependencies/angular.min.js:39:310)
at http://laravel.app/app/js/dependencies/angular.min.js:80:313
at A.link (http://laravel.app/app/js/dependencies/angular-route.min.js:7:268)
at aa (http://laravel.app/app/js/dependencies/angular.min.js:73:90)
at K (http://laravel.app/app/js/dependencies/angular.min.js:62:39)
at g (http://laravel.app/app/js/dependencies/angular.min.js:54:410)
at http://laravel.app/app/js/dependencies/angular.min.js:53:480
at http://laravel.app/app/js/dependencies/angular.min.js:55:397 <div ng-view="" class="view-frame ng-scope" data-ng-animate="1">(anonymous function) # angular.min.js:107
http://laravel.app/models/dom Failed to load resource: the server responded with a status of 404 (Not Found)
Seems like in your controller
function ProfileCtrl($scope) {
$scope.profile = Profile.query();
}
you didn't inject Profile factory.