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).
Related
i start working with angular 1.x boilerplate and have 1 problem, i can`t send into resolver promise from service
function ExampleService($http) {
'ngInject';
const service = {};
let getTasks = ()=> {
return $http.get('tasks');
};
service.isReady = new Promise((resolve, reject)=> {
getTasks().then(
(data) => {
resolve(data);
},
(err, status) => {
reject(err, status);
});
});
return service;
}
export default {
name: 'ExampleService',
fn: ExampleService
};
But when i try inject ,y service to on_config.js i have error
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:unpr] Unknown provider: ExampleService
My stateProvider
$stateProvider
.state('Home', {
url: '/',
controller: 'ExampleCtrl as home',
templateUrl: 'home.html',
title: 'Home',
resolve:{example:ExampleService.isReady}
})
Maybe i do something wrong or you can suggest how can i impelemt logic for preloading some data to app before rendering first controller
P.S. link to bolerplate
Services can't be injected into config blocks. They need to be injected in resolver functions:
$stateProvider
.state('Home', {
url: '/',
controller: 'ExampleCtrl as home',
templateUrl: 'home.html',
title: 'Home',
resolve:{
example: function (ExampleService) {
return ExampleService.isReady();
}
})
Also the isReady needs to be a function, not a new promise:
service.isReady = () => {
return getTasks().then(response => response.data);
}
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>
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
(AngularJS v1.2.28 - angular-ui-router v0.2.13
In my index.html I have the following:
<div class="wrapper" ui-view></div>
In my app.js I have my stateProvider set up as:
$urlRouterProvider.otherwise('/app/search');
$stateProvider.state("app", {
url: '/home',
controller: 'MainCtrl',
templateUrl: 'views/main.html'
}).state('app.search', {
resolve: {
categories: function ($q, $stateParams, LiveOak) {
var deferred = $q.defer();
LiveOak.readMembers('/liveoak/storage/categories', {
success: function (categories) {
deferred.resolve(categories);
},
error: function (error) {
console.error(error);
}
});
return deferred.promise;
}
},
url: '/search',
templateUrl: 'views/search.html',
controller: 'SearchCtrl'
}
).state('app.subjects', {
url: '/subjects/:id',
abstract:true,
templateUrl: '<ui-view/>'
}
).state('app.subjects.default', {
resolve: {
subjects: function ($q, $stateParams, LiveOak) {
var deferred = $q.defer();
var categoryId = $stateParams.id;
var query = {
categoryId : categoryId
};
LiveOak.readMembers('/liveoak/storage/subjects', {
query: query,
success: function (subjects) {
console.log("subjects resolved")
deferred.resolve(subjects);
},
error: function (error) {
console.error(error);
}
});
return deferred.promise;
},
instructors: function ($q, $stateParams, LiveOak) {
}
},
url: '',
templateUrl: 'views/subject.html',
controller: 'SubjectCtrl'
}).state('app.subjects.authors', { //THIS IS NOT RECOGNIZED
resolve: {
authors: function ($q, $stateParams, LiveOak) {
var deferred = $q.defer();
var subjectId = $stateParams.id;
var query = {
query.subjectId : subjectId
};
LiveOak.readMembers('/liveoak/storage/authors', {
query: query,
success: function (authors) {
deferred.resolve(authors);
},
error: function (error) {
console.error(error);
}
}
);
return deferred.promise;
}
},
url: '/subjects/:id/authors/',
templateUrl: '../views/subjects.authors.html',
controller: 'AuthorsCtrl'
}
);
}]);
I am wrestling with the state: app.subjects.authors. Right now app.search and app.subjects work. However, when I try to go the the state: app.subjects.authors it is not even recognized. I set up up a state app.subject as abstract, so hopefully app.subjects.authors wouldn't be overridden by app.subjects. Anyone see anything out of the ordinary?
Thanks for the help!!
My subject.html looks like this:
<div ng-repeat="subject in subjects" class="mdl-cell mdl-cell--4-col">
<a href="#/app/subjects/{{subject.categoryId}}/authors">
<span>{{subject.name}}</span>
</a>
</div>
Just change templateUrl: to template:. You don't need abstract:.
.state('app.subjects', {
url: '/subjects/:id',
template: '<ui-view/>'
})
You shall have:
url: '/authors',
Instead of:
url: '/subjects/:id/authors/',
Because url is relative. So the url of child state is continuation of parent state's url. So authors state will match following url:
/home/subjects/:id/authors
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