Failed to load modules - javascript

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

Related

Angularjs - Inject factory without reference

I have the following code:
main.js
angular.controller('myCtrl', function($scope, $rootScope) {
$scope.name = "Bob";
}
myservices.js
angular.factory('myService', function($http) {
var myService = {
async: function(params) {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get("http://myws/user/info/"+params).then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
How can inject myService in myCtrl ? considering they are in two separated files.
We need to add in order all of our scripts we have created to run this angular, take note the order:
<script src="angular.js"></script>
<script src="main.js"></script>
<script src="myservices.js"></script>
main.js should look like:
var app = angular.module("MyModule", []);
app.controller('myCtrl', function($scope, $rootScope, myService) { /* implementation */})
services.js should look like:
app.factory('myService', function($http) { /* implementation */});
So in our main.js we are creating a module to attach all of our services, factories, providers, values, constants, controllers and directives. It also allows us to put the config and run phase functions in.
The module is instantiated via:
angular.module("MyModule", []);
We're providing a second argument of other dependant modules
If we needed to, we could ask angular for the module again, in the case of use javascript modules:
var app = angular.module("MyModule");
Below are several thing you need to do.
Should be they should belong same/different angular module(if its different module then you have inject into main module to use it).
You need to use angular.module('myApp') to bind components to it, so that the service will be available in that module.
Code
//app.js
angular.module('myApp', ['myApp.service']); //this should be module definition somewhere
//service.js
angular.module('myApp.service', [])
angular.module('myApp.service').factory('myService', function($http) {
//service code
});
//controller.js
angular.module('myApp').controller('myCtrl', function($scope, $rootScope, myService) {
console.log(myService); //service instance here
$scope.name = "Bob";
}
you can inject service in your controller
like:
main.js:
angular.module('myApp', []).controller('myController', ['$scope', 'myService',
function ($scope, myService) {
}
]);
myService.js:
angular.module('myApp').factory('myService', function($http) {
//service code
});
for different file but same module then ensure that file is loaded before use.
Make sure the files are both actually loaded. How to do that is up to you, perhaps you're using some implementation of require(), or you simply list all the files in your HTML as <script> tags.
Clarify what module structure you want to have. Should both be part of the same module, or should they be separate modules?
Same module: One file needs to declare the module, the other needs to extend it:
angular.module('Foo', []) // declares new module
.controller(..)
angular.module('Foo') // extends existing module
.factory(..)
Different modules:
angular.module('Foo', []) // declares new module
.factory(..)
angular.module('Bar', ['Foo']) // declares new module
.controller(..) // and imports other module
Inject into the controller:
.controller('myCtrl', function ($scope, myService) ..

angularjs - ui-router add module

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');

AngularJS Unit Testing - multiple mocks and providers

I'm starting to do unit testing for my Angular app, and I had some questions on how to actually structure the tests folder. I basically used the yeoman angular generator, so it comes with Jasmine and Karma pre-configured.
Here's a scenario of what I'm trying to test...
I have a "PageHeaderDirective" which displays a user's name and email (like a welcome message) as well as a logout link. The code for the page header directive is inconsequential, but I do need to hit the "/user" endpoint from the backend to get the user's details. Here is the code for UserService which is injected into PageHeaderDirective:
/**
* #ngdoc function
* #name Common.service.UserService
* #description
* Service to retrieve a {#link User} from the backend.
*/
(function () {
'use strict';
angular.module('Common').service('UserService', UserService);
UserService.$inject = ['User', 'Restangular'];
/**
* User service function.
* #param User The {#link User} provider.
* #param Restangular The restangular provider.
*/
function UserService(User, Restangular) {
var userPromise;
return {
getUser: getUser
};
/**
* Retrieves a {#link User} instance from the /user endpoint.
* #returns A promise to be resolved with a {#link User} instance.
*/
function getUser() {
if(!userPromise) {
userPromise = Restangular.one('user').get().then(function(data) {
return User.factory(data);
});
}
return userPromise;
}
}
})();
Here is a really simple test for PageHeaderDirective:
describe('Pageheader Tests', function() {
'use strict';
var scope;
var element;
beforeEach(module('templates'));
beforeEach(module('Common'));
beforeEach(inject(function(_$rootScope_, $compile) {
scope = _$rootScope_.$new();
scope.message = 'Test message';
element = '<ft-page-header message="message" page="home"></ft-page-header>';
element = $compile(element)(scope);
scope.$digest();
}));
it('should render a page header with the logo and username', function() {
expect(element.find('.logo-text').length).toBe(1);
var isolateScope = element.isolateScope();
expect(isolateScope.name).toBe('test');
});
});
Now, as you can probably tell, I'm getting an unknown provider error "Unknown provider: RestangularProvider <- Restangular <- UserService <- pageHeaderDirective" because I haven't injected it into the tests.
I've read that you can do something like beforeEach(function(){ module(function($provide) { $provide.service('UserService', function() { ... }})}); in each test file, but I don't really want to do that any time a directive/controller uses the UserService. How do I break that portion out of each test file and put it into its own "UserService.mock.js" file? If it's possible, how would I inject the "UserService.mock.js" into my tests?
Secondly, I'm also injecting Restangular into PageHeaderDirective to logout the user (Restangular.one('logout').get().then...). How do I mock this (I don't ever want to call the API endpoints)?
Lastly, if there are other providers that I am injecting ($document, $localStorage, $window), do I need to inject all of these into the tests as well? If so, how?
Thanks!
In case anyone wants to do what I have done (separate your mocks into different files so you don't need to copy-paste things a lot), here is what I have found out.
// /test/mock/UserService.mock.js
(function() {
"use strict";
angular.module('mocks.Common').service('UserService', mock);
mock.$inject = ['$q', 'User'];
function mock($q, User) {
return {
getUser : getUser
};
function getUser() {
return $q.when(User.factory({
firstName: 'test',
email: 'test#gmail.com',
id: 1
}));
}
}
})();
So first, you need to make sure your module (in this case I made "mocks.Common") is created. In a separate file I put this line: angular.module('mocks.Common', []); This creates my "mocks.Common" module. Then, I created a mock called "UserService" and used $q to return a promise with some dummy data. The User.factory portion is just a factory function within my real App from the Common module.
Once you have the above mocked "UserService", make sure to inject the modules in the correct order during your test's setup. Like so:
module('app');
module('templates');
module('mocks.Common');
Now, when my test runs, PageHeaderDirective will use the mocked "UserService" instead of the real one!
As for my second question: I haven't actually done it yet, but I believe I'll be able to use $httpBackend to test any Restangular functionality.
Thirdly, I figured out that if you just run module('appName') in all of your tests, you should automatically get any required dependencies. For example, here is my module definition for my entire app:
angular.module('app', [
'Common',
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'ngDialog',
'ngStorage',
'lodash',
'smart-table',
'rhombus',
'helpers',
'restangular',
'moment',
'cgBusy',
'duScroll'
])
So when I do module('app') I get all of these dependencies automatically in my tests (note the "Common" dependency in my app config).

MVC4 & AngularJS error when using ngAnimate as a dependency

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
}]);
})();

AngularJS module creation inside RequireJS define with dependency

I'm having an issue creating an AngularJS module inside a RequireJS define method.
When I make reference to the ui-router module that I need, Angular tells me:
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:nomod] Module 'myApp' 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.
This only happens if I define uiRouter in the requireJS dependency list.
Here's my code:
require.config({
paths : {
'angular' : "/script/lib/angular",
'uiRouter' :"/script/lib/angular-ui-router",
},
shim : {
'angular': {
exports : 'angular'
},
'uiRouter' : {
deps : ['angular']
}
}
});
define(['angular', 'uiRouter'], function (angular) {
var module = angular.module('myApp', []);
});
If I take uiRouter out of the define dependency array, everything works as expected. What am I doing wrong?
You need to add the ui.router to your module.
define(['angular', 'uiRouter'], function (angular) {
var module = angular.module('myApp', ['ui.router']);
});
EDIT: I added the following:
define('myApp', ['angular', 'uiRouter'], function (angular) {
var module = angular.module('myApp', ['ui.router']);
});

Categories