I have a main.html with multiple subpages:users.html,usergroups.html,... which all of them have their own app files and controllers separately: mainapp.js,usersapp.js,usergroupsapp.js,...
And I use ui-router to route to particular sub page as needed:
var myApp = angular.module("myApp",['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('users', {
url: "/users",
templateUrl: "pages/users.html",
controller : 'UsersCtrl'
})
.state('usergroups', {
url: "/usergroups",
templateUrl: "pages/usergroups.html",
controller : 'UsergroupsCtrl'
})
...
Everything works fine until I need to use one of the module multiselect.jsin my usergroups.html. When I added it directly to UsergroupsCtrl in usergroupsapp.js:
var app= angular.module('myApp',['am.multiselect']);
...
But immediately I have an error:
Error: [ng:areq] Argument 'MainCtrl' is not a function, got undefined
Which MainCtrl is from main app.js.
How can I resolve this issue?
Here is correct way to add am.multiselect module dependency to your main myApp module:
var myApp = angular.module("myApp", ['ui.router', 'am.multiselect']);
In usergroupsapp.js you should just have module getter, not setter (don't recreate module once again). Note, that there are no [...] when you retrieve existing module:
var app = angular.module('myApp');
Related
I have a hard time understanding this. I'm attempting to put controllers in separate files so that they only deal with 1 thing, ideally, a partial view
My folder structure is like this...
My app.js file is like this.
angular.module('mikevarela', ['ui.router', 'mikevarela.controller.home', 'mikevarela.controller.about', 'mikevarela.controller.audio'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: '../partials/home.partial.html',
controller: 'HomeController'
})
.state('about', {
url: '/about',
templateUrl: '../partials/about.partial.html',
controller: 'AboutController'
})
.state('audio', {
url: '/audio',
templateUrl: '../partials/audio.partial.html',
controller: 'AudioController'
});
});
and my controllers each have a module like this...
angular.module('mikevarela.controller.home', [])
.controller('HomeController', ['$scope', function($scope) {
$scope.title = 'Mike Varela Home Page';
}]);
My issues comes with the intial app declaration. I don't want to have to inject all the controllers in the main array app definition, that would be cumbersome and long winded. Isn't there a way to define the controller at the controller file. Kind of like this
angular.module('mikevarela', []).controller('HomeController', ['$scope', function($scope) {
// stuff here
}]);
Use angular.module('mikevarela').controller..... in subsequent files.
angular.module('mikevarela',[]).controller.....
is equivalent to redefining your app. The second param is requires array.
Quoting official angular.module docs
requires
(optional)
!Array.=
If specified then new module is being created. If unspecified then the module is being retrieved for further configuration.
About your Controllers...
I think you're loading the controllers incorrectly.
You don't need to declare controllers as a dependency. Rather stating module.controller('yourController)` makes that controller available throughout the module.
If your controllers are in separate files, all you need to do to make it available is load it in with a script tag. e.g.
<script src="app.js"></script>
<script src="controller1.js"></script>
<script src="controller2.js"></script>
About your Application Structure...
This is not related to your question, but just coming from someone who's developed using Angular, I'd recommend not grouping your application by controllers/ by rather by feature. See: https://scotch.io/tutorials/angularjs-best-practices-directory-structure
I'm trying to combine Angular 1.5, UI Router using ES6 import modules syntax with Babel & Webpack.
In my app.js I have:
'use strict';
import angular from 'angular';
import uiRouter from 'angular-ui-router';
...
import LoginCtrl from './login/login.ctrl.js'
const app = angular.module("app", [
uiRouter,
...
])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: '...',
controller: LoginCtrl,
controllerAs: 'login'
})
});
In login/login.ctrl.js I have:
'use strict';
export default app.controller("LoginCtrl", function() {
//code here
});
When I started my app I have following error message:
ReferenceError: app is not defined
bundle.js:35422:2
Error: [$injector:modulerr] Failed to instantiate module app due to:
[$injector:nomod] Module 'app' is not available! You either misspelled the module name or forgot to load it.
And second question. How can I use controller: "loginCtrl as login" syntax with ES6 import/export?
You are referring to 'app' variable inside your 'login/login.ctrl.js' but the variable is not defined (because you are importing the controller before defining it).
EDIT: Anyway each module has its own scope so you can't refer to variable from different module this way.
The solution I have in my mind is following:
Inside 'login/login.ctrl.js' create new module
'use strict';
import angular from 'angular';
angular.module('ctrlsModule', [])
.controller('LoginCtrl', function () {
});
Add the module as dependence of your main 'app' module
'use strict';
import angular from 'angular';
import uiRouter from 'angular-ui-router';
...
import './login/login.ctrl.js';
angular.module('app', [uiRouter, 'ctrlsModule', ...])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: '...',
controller: 'LoginCtrl',
controllerAs: 'login'
});
});
I haven't tested the code but I believe you can see what I mean. Not sure what you mean with the second question but controllerAs in ES6 should work the same way as in ES5.
Hello i am trying to develop a web app with angular. I have added the ng-app="appApp" to the html file and also the .js files.
main.controller.js
(function () {
'use strict';
// register the controller as MainController
angular
.module('appApp.main')
.controller('MainController', MainController);
/**
* #ngdoc function
* #name appApp.main.provider:MainController
* #description
* Provider of the {#link appApp.main.controller:MainController MainController}
*
* #param {Service} $scope The scope service to use
* #param {Service} $http The http service to use
*/
// MainController.$inject = [];
function MainController() {
var vm = this;
}
})();
main.js
(function () {
'use strict';
// register the route config on the application
angular
.module('appApp.main', ['ui.router'])
.config(configMainRoute)
// inject configMainRoute dependencies
configMainRoute.$inject = ['$stateProvider', 'mainMenuProvider'];
// route config function configuring the passed $stateProvider
function configMainRoute($stateProvider, mainMenuProvider) {
var mainState = {
name: 'main',
url: '/',
authenticate: true,
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'vm'
};
$stateProvider.state(mainState);
mainMenuProvider.addMenuItem({
name: 'Home',
state: mainState.name,
order: 1
});
}
})();
app.js
(function () {
'use strict';
angular
.module('appApp', [
// Add modules below
'ngCookies',
'ngResource',
'ngSanitize',
'ngMessages',
'ngMaterial',
'ui.router',
'btford.socket-io',
'appApp.main'
])
.config(appConfig)
.run(appRun);
...........
When i run the app i get this errors:
Error: [ng:areq] Argument 'MainController' is not a function, got undefined
Uncaught Error: [$injector:nomod] Module 'appApp.main' 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.
How can i fix that errors? Thank you
The first thing is :
In the html you've written
ng-app="appApp"
But in the module definition you've written
angular
.module('appApp.main', ['ui.router'])
The module names should be same unless you've another appApp module and you add the "appApp.main" module as dependency.
Another thing is as you've using "ui-router" you need to link the js library file of ui-router in the html along with angular library file.
Just check the sequence of js files. At first angular, then all library js, then app, main, main controller
I think,
1.You should call ng-app="appApp.main" or
2.You should initially declare appApp module. You should replace some code in main.js
angular.module('appApp.main', []);
angular.module('appApp', [
'ui.router',
'appApp.main'
])...
Also, remove [ui.router] in main.js. It has declared in app.js
This is my index.js file
'use strict';
angular.module('wildenglish', ['ngAnimate', 'ngTouch', 'restangular', 'ngRoute', 'ui.bootstrap'])
.config(function ($routeProvider, RestangularProvider) {
RestangularProvider.setBaseUrl('https://www.googleapis.com/calendar/v3/calendars/googleCalendarID');
$routeProvider
.when('/', {
templateUrl: 'app/main/main.html',
controller: 'MainCtrl',
resolve: {
calendarEvents: function(Restangular){
return Restangular.one('eventsAUTHKEY').get();
}
}
})
.otherwise({
redirectTo: '/'
});
})
And my main controller.js
'use strict';
angular.module('wildenglish')
.controller('MainCtrl', function(Restangular, calendarEvents) {
var self = this,
events = calendarEvents,
items = events.items;
});
The Error I'm receiving when I try to use in the HTML is:
Error: [$injector:unpr] Unknown provider: calendarEventsProvider <- calendarEvents <- MainCtrl
So I am trying to figure out how I can utilize the information that I am getting back from that Promise which I can log in the console to be accessible to the HTML via the controller
Do I need a service or factory? and where would that go?
Thank you in advance for your help
Assign the events returned by the resolved promise to your controller scope. You'll need to change the depencies your injecting into your controller. You can leave out Restangular since you are resolving your promise in your route but you do need $scope:
angular.module('wildenglish').controller('MainCtrl', function($scope, calendarEvents) {
// i'm assuming the following logs your events to your console
// if not you're having a problem with your Restangular request
console.log(calendarEvents);
// Assign calendarEvents to your $scope
$scope.events = calendarEvents;
});
Now you can use the events in your HTML template (assuming each event has a property called 'name'):
<ul>
<li ng-repeat="event in events">{{event.name}}</li>
</ul>
Sorry, I missed the answer above which is already the correct answer.
There was a similar problem here:
AngularJS, resolve and unknown provider
Basically if you are using the routeProvider to assign your controller in your script file you cannot use ng-controller in your template.
I'm new to Angular and dependency injection. I'm receiving the following error on page load. I'm attempting to create a form wizard like this example in .Net/MVC4. Any help is greatly appreciated.
Uncaught Error: [$injector:unpr] Unknown provider: $$qProvider <- $$q <- $animate <- $compile
Scripts loading in view head:
<script src="#Url.Content("/Scripts/bower_components/angular/angular.js")"></script>
<script src="#Url.Content("/Scripts/bower_components/angular-ui-router/release/angular-ui-router.js")"></script>
<script src="#Url.Content("/Scripts/bower_components/angular-animate/angular-animate.js")"></script>
<script src="#Url.Content("/Scripts/modules/long-form-app-module/LongFormApp.js")"></script>
<script src="#Url.Content("/Scripts/modules/long-form-app-module/LongFormController.js")"></script>
HTML Markup
<div class="application">
<!-- Inject partial view from router -->
<section ui-view></section>
</div>
LongFormApp.js Script
(function () {
'use strict';
// Create our app and inject ngAnimate and ui-router
angular.module('GllApp', ['longFormController'])
.config(function ($stateProvider, $urlRouterProvider) {
// Catch all route
// By default send user to question one
$urlRouterProvider.otherwise('/home');
$stateProvider
// Route to show start of form
.state('home', {
url: '/home',
templateUrl: 'LongForm.html',
controller: 'LongFormController'
})
// Route to show start of form
.state('home.q01', {
url: '/home/q01',
templateUrl: 'LongFormQuestion01.html'
});
});
})();
LongFormController.js Script
(function () {
'use strict';
angular.module('longFormController', ['ngAnimate', 'ui.router'])
.controller('LongFormController', ['$scope', function ($scope) {
// do stuff
}]);
})();
I just fixed this exact problem with my project. The root cause was I was depending on "angular-animate": "~1.3.0", so bower was using Angular v1.3 even though the rest of the project was depending on Angular 1.2.
Just use
"angular-animate": "~1.2.0"
instead of
"angular-animate": "~1.3.0"
in your bower.json file. After a bower install everything should work!
You are creating the module twice, the second one you are loading replaces the first one. I'm not sure what order you want your dependencies in, but you probably just want one app:
var myGllApp = angular.module('GllApp', ['ngAnimate', 'ui.router']);
And load your controller script later and add it to your exising module by not passing the dependency list to angular.module:
angular.module('GllApp')
.controller('LongFormController', ['$scope', function ($scope) {
I've refactored the code you posted and added comments. Try this and see if you receive another error?
This is assuming you are loading: First Snippet > Second Snippet
(function () {
//use this inside of the SC function or else use strict will be used globally
//and cause unexpected results
'use strict';
// Create our app and inject ngAnimate and ui-router
// You don't need to create this variable if it is for scoping reasons,
// since you have already created a defined scope within the Self-Calling function
angular.module('GllApp', ['ngAnimate', 'ui.router'])
.config(function ($stateProvider, $urlRouterProvider) {
// Catch all route
// By default send user to question one
$urlRouterProvider.otherwise('/home');
$stateProvider
// Route to show start of form
.state('home', {
url: '/home',
templateUrl: 'form.html',
controller: 'LongFormController'
})
// Route to show start of form
.state('home.q01', {
url: '/home/q01',
templateUrl: 'form-q01.html'
});
});
})();
(function () {
'use strict';
angular.module('GllApp', ['ngAnimate']) //since you are not using stateProvider here you do not need to inject ui.router
.controller('LongFormController', ['$scope', function ($scope) {
// do stuff
}]);
})();