I can't get controller working despite being registered
I am defining my controller like below
(function () {
'use strict';
function EntityModulesCtrl(UserManagement, getEntityModules) {
let ctrl = this;
console.log('loggging from entityModules ctrl...');
console.log(getEntityModules);
ctrl.saveMapping = function () {
let params = {
modules: ctrl.selectedModules,
entity: ctrl.selectedEntity
};
UserManagement.saveModuleEntityMapping(params).then(function(res){
console.log(res);
});
}
}
angular.module('mean.user_management')
.controller('EntityModulesCtrl', EntityModulesCtrl);
EntityModulesCtrl.$inject = ['UserManagement', 'getEntityModules'];
});
My route is
(function() {
'use strict';
function UserManagement($stateProvider) {
$stateProvider.state('dashboard', {
url: '/dashboard',
templateUrl: 'user_management/views/index.html',
resolve: {
// dashboardConfig: function () {
// var roleType = localStorage.getItem('roleType');
// }
}
}).state('userManagement circles example', {
url: '/userManagement/example/:circle',
templateUrl: 'user_management/views/example.html'
}).state('dashboard.entityModulesMapping', {
url: '/userManagement/mapEntityModules',
templateUrl: 'user_management/views/entityModules.html',
controller: 'user_management/controllers/EntityModulesCtrl.js',
controllerAs: '$ctrl',
resolve: {
getEntityModules: function (UserManagement) {
return UserManagement.getEntityModules().then(function (res) {
console.log("logging from mapEntityModules resolve...");
console.log(res);
return res;
})
}
}
});
}
angular.module('mean.user_management')
.config(UserManagement);
UserManagement.$inject = ['$stateProvider'];
})();
I have tried using
controller: EntityModulesCtrl
controller: 'EntityModulesCtrl'
controller: "path_to_my_controller_file"
But it did not work.
Your module should be with dependencies,
angular
.module('mean.user_management',[])
.config(UserManagement);
In your script add
controller: 'EntityModulesCtrl',
in place of
controller: 'user_management/controllers/EntityModulesCtrl.js',
And make sure you add the controllerscript file to your html page.
<script src="user_management/controllers/EntityModulesCtrl.js"></script>
Related
I am a Web Developer with experience over 5 years. Nowadays I learnt MEAN-stack web site developing way and began to start MEAN-stack project. Then I have some problems in front-end section(angular control managing).
My main problem is my angular controller js file causes 2 browser error. like as following.
The first error is as follows:
aangular.js:68 Uncaught Error: [$injector:nomod] Module 'app' is not available!
You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.(…)(anonymous function)
# angular.js:68(anonymous function)
# angular.js:2082ensure
# angular.js:2006module
# angular.js:2080(anonymous function)
# UsersService.js:4(anonymous function)
# UsersService.js:111
The second error is as follows:
angular.js:13920 Error: [ng:areq] Argument 'Users.Controller' is not a function, got undefined
My front-end code structure is the following.
controllers
users.controller.js, account.controller.js, projects.controller.js and so on.
services
UsersService.js, AccountService.js and so on
app.js (middleware section)
views
index.html, htmls corresponding to each controller js
lets take a look code in detail.
App.js file:
(function () {
angular.module('app', ['ui.router'])
.config(config)
.run(run);
function config($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/");
$stateProvider
.state('home', {
url: '/',
template: '<h1>Unpasan Admin Page!</h1>',
controller: 'Users.Controller',
controllerAs: 'vm',
//data: { activeTab: 'home' }
})
.state('account', {
url: '/account',
templateUrl: 'views/account.html',
controller: 'Accounts.Controller',
controllerAs: 'vm',
data: { activeTab: 'account' }
})
.state('client', {
url: '/client',
templateUrl: 'views/client.html',
controller: 'Clients.Controller',
controllerAs: 'vm',
data: { activeTab: 'client' }
})
.state('user', {
url: '/user',
templateUrl: 'views/user.html',
controller: 'Users.Controller',
controllerAs: 'vm',
data: { activeTab: 'client' }
})
.state('project', {
url: '/project',
templateUrl: 'views/project.html',
controller: 'Projects.Controller',
controllerAs: 'vm',
data: { activeTab: 'project' }
});
}
UsersService.js:
(function () {
angular
.module('app')
.factory('UserService', function(){
var service = {};
service.GetCurrent = GetCurrent;
service.GetAll = GetAll;
service.GetById = GetById;
service.GetByUsername = GetByUsername;
service.Create = Create;
service.Update = Update;
service.Delete = Delete;
return service;
function GetCurrent() {
return $http.get('/api/users/current').then(handleSuccess, handleError);
}
function GetAll() {
return $http.get('/api/users').then(handleSuccess, handleError);
}
function GetById(_id) {
return $http.get('/api/users/' + _id).then(handleSuccess, handleError);
}
function GetByUsername(username) {
return $http.get('/api/users/' + username).then(handleSuccess, handleError);
}
function Create(user) {
return $http.post('/api/users', user).then(handleSuccess, handleError);
}
function Update(user) {
return $http.put('/api/users/' + user._id, user).then(handleSuccess, handleError);
}
function Delete(_id) {
return $http.delete('/api/users/' + _id).then(handleSuccess, handleError);
}
// private functions
function handleSuccess(res) {
return res.data;
}
function handleError(res) {
return $q.reject(res.data);
}
});
})();
users.controller.js
angular.module('app',[]).controller('UsersController', ['$scope, UserService', function($scope, UserService){
$scope.users = null;
initController();
console.log('Users.Controller:initController');
function initController() { // get current user
UserService.getAllUser().then(function (users) {
$scope.users = users;
});
}
function saveUser() {
UserService.Update(vm.user)
.then(function () {
FlashService.Success('User updated');
})
.catch(function (error) {
FlashService.Error(error);
});
}
function deleteUser() {
UserService.Delete(vm.user._id)
.then(function () {
// log user out
$window.location = '/login';
})
.catch(function (error) {
FlashService.Error(error);
});
}
}] );
When I clicked elements of sidebar in index.html, should be exchanged content of 'ui-view' tag.
The error message mentioned above is case of clicked users 'ui tag'.
Instead of controller: 'Users.Controller', it should be controller: 'UsersController' (see object passed into the state definition for 'home'). You should pass in the name of the controller (UsersController), not the file name (users.controller).
I have ui router state like this:
$stateProvider.state('parent', {
templateUrl: 'tpl/a.html',
resolve: {
resA: function() {
return { 'value': 'A' };
}
},
controller: function($scope, resA) {
$scope.resA = resA.value;
}
});
In the template html I use another controller (child controller). This child controller need resolve dependency from ui router state. But, it is not injected to child controller.
tpl/a.html
<h1>Hello</h1>
<div ng-controller="ChildCtrl">
</div>
ChildCtrl
var app = angular.module('app', []);
app.controller('ChildCtrl', function($scope, resA) {
// some codes
});
I got an error, that resA unkonwn in ChildCtrl. How to inject resA in ChildCtrl?
I see 3 options:
1) put the value in $scope of parent controller
//it would be available in child controller in `$scope.a`
$stateProvider.state('parent', {
templateUrl: 'tpl/a.html',
resolve: {
resA: function() {
return { 'value': 'A' };
}
},
controller: function($scope, resA) {
$scope.resA = resA.value;
}
})
.state('parent.child', {
templateUrl: 'tpl/child.html',
controller: function($scope) {
console.log($scope.resA) //'{value: "A"}'
}
});
2) put child controller as controller for a sub-route, and resolve resA there as well
var a = { 'value': 'A' };
$stateProvider.state('parent', {
templateUrl: 'tpl/a.html',
resolve: {
resA: function() {
return a;
}
},
controller: function($scope, resA) {
$scope.resA = resA.value;
}
})
.state('parent.child', {
templateUrl: 'tpl/child.html',
resolve: {
resA: function() {
return a;
}
},
controller: function($scope, resA) {
$scope.resA = resA.value;
}
});
3) make some service that will provide the data (that now is stored in resA) for controller and inject it to both controllers
Checkout #BotanMan's answer.
Also another way, which is similar to the 3. answer.
Put your resource into a service.
var app = angular.module('app');
app.service('resA', function() {
// your service here
});
And include it like so :
$stateProvider.state('parent', {
templateUrl: 'tpl/a.html',
resolve: {
resA: 'resA' //your service name
},
controller: function($scope, resA) {
$scope.resA = resA.value;
}
});
So you can use that resource, like you intended :
var app = angular.module('app', []);
app.controller('ChildCtrl', function($scope, resA) { //now it should work
// some codes
});
See the docs on resolve.
So I have this routing piece of code:-
$stateProvider.state('app.dashboard', {
url: "/dashboard",
templateUrl: "app/components/dashboard/dashboard.html"
, resolve: {
factory: ["$ocLazyLoad", "$q", ['jquery-sparkline', 'dashboardCtrl'], loadSequence]
},
title: 'Dashboard',
ncyBreadcrumb: {
label: 'Dashboard'
}
And i have this function:-
function loadSequence($ocLL, $q, files) {
}
so basically what i want to do is passing ['jquery-sparkline', 'dashboardCtrl'] to the function loadSequence, these values are simple string values. Is there a way to this.
Maybe i don't understand you
(function () {
'use strict';
angular
.module('plunker')
.config(config);
config.$inject = ['$stateProvider'];
/* #ngInject */
function config($stateProvider) {
$stateProvider
.state('app.dashboard', {
url: '/dashboard',
templateUrl: 'app/components/dashboard/dashboard.html',
controller: 'dashboardCtrl',
controllerAs: 'dashboard',
resolve: {
dashboardService: dashboardService
},
title: 'Dashboard',
ncyBreadcrumb: {
label: 'Dashboard'
}
});
}
dashboardService.$inject = ['$ocLazyLoad', '$q'];
function dashboardService($ocLazyLoad, $q) {
return buttonService.getButtons().then(function (data) {
return data;
});
}
})();
(function () {
'use strict';
angular
.module('app.dashboard')
.controller('dashboardCtrl', dashboardCtrl);
dashboardCtrl.$inject = ['dashboardService','jquery-sparkline'];
function dashboardCtrl(dashboardService,jquery-sparkline) {
var vm = this;
vm.loadSequence = loadSequence;
function loadSequence($ocLL, $q, files) {
}
}
})();
Factory
(function () {
angular.module("common.script").factory("expenseResource", ["$resource", expenseResource]);
function expenseResource($resource) {
var expenceCategory = function ($resource) {
return $resource("api/expenceCategory/:expenceCategoryId");
}
return {
expenceCategory: expenceCategory
};
}
})();
Controller
(function () {
var app = angular.module("ExpenceManagerApp", ["ui.router", "common.script", "expenseResourceMock"]);
app.config(["$stateProvider","$urlRouterProvider", function ($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("HomePage", {
url:"/",
templateUrl: "App/Main/homePage.html",
})
.state("Settings", {
url: "/Settings",
templateUrl: "App/Expense/settingsPage.html",
})
.state("expenceCategoryEdit", {
url: "/expenceCategoryEdit",
templateUrl: "App/Expense/editExpenseCategory.html",
controller: "editExpenseCategoryCtrl as vm",
resolve: {
expenseResource: "expenseResource",
expenseCategoryList: function (expenseResource) {
return expenseResource.expenceCategory.query().$promise;
}
}
})
}]);
}());
expenceCategory is a function, so use it as function:
expenseResource.expenceCategory().query().$promise
OR define expenceCategory as field:
return {
expenceCategory: expenceCategory()
};
NB: your service creates new $resource each time it is launched. It should be just:
function expenseResource($resource) {
return $resource("api/expenceCategory/:expenceCategoryId");
}
And in controller:
expenseResource.query().$promise
I want to make my views show only after the initial data is fetched and i am trying to accomplish this with a route resolve, but i can't get it to work. What am i doing wrong? Also my angular skills are a bit shabby so i aplogize in advance if my question is dumb.
Application.js :
var Application = angular.module('ReporterApplication', ['ngRoute']);
Application.config(['$routeProvider', '$interpolateProvider',
function($routeProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
$routeProvider
.when('/packing/scan.html', {
templateUrl: 'packing/scan.html',
controller: 'PackingScanController',
resolve: {
initData : Application.PackingScanInit()
}
})
.when('/packing/stats.html', {
templateUrl: 'packing/stats.html',
controller: 'PackingStatisticsController'
})
etc
and here is my Scan.js file :
Application.PackingScanInit = function ($q,$timeout,$http) {
var serverData = "";
$http.get('/packing/scan.action')
.success(function(data){
serverData = data;
})
.error(function(data){
serverData = data;
});
return serverData;
}
Application.controller('PackingScanController', ['initData', '$scope', '$http', function(initData, $scope, $http) {
var packer = this;
// Message log model
packer.messageLog = [{
status : "",
message : null
}];
the files are included in this order.
service are singletons means there are initialized only one but time but if you simply return from service it will be called one time but if you return a function from service it will be called again and again .See Below Sample for working.
var app = angular.module('ajay.singhApp', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/view1', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
resolve: {
myVar: function (repoService) {
return repoService.getItems().then(function (response) {
return response.data;
});
}
}
})
.when('/view2', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/view1'
});
}]);
app.factory('repoService', function ($http) {
return {
getItems: function () {
return $http.get('TextFile.txt');
}
};
});
Try this:
Application.PackingScanInit = function ($q,$timeout,$http) {
return $http.get('/packing/scan.action')
.success(function(data){
return data;
})
.error(function(data){
return data;
});
}
Also you have to adjust your resolve to this:
resolve: {
initData : Application.PackingScanInit
}
Here is a specific working example:
(function() {
angular.module('app',['ngRoute']);
function TestCtrl($scope, initData) {
$scope.value = initData;
}
angular.module('app').config(function($routeProvider) {
$routeProvider.otherwise({
template: '`<p>Dude {{value}}</p>`',
controller: TestCtrl,
resolve: {
initData: function($http) {
return $http.get('test.json') //change to test-e.json to test error case
.then(function(resp) {
return resp.data.value; //success response
}, function() {
return 'Not Found'; // error response
});
}
}
});
});
})();
http://plnkr.co/edit/SPR3jLshcpafrALr4qZN?p=preview