AngularJS can't find components when using IIFEs - angularjs

The angularjs style guide recommends using IIFEs to wrap angular components. However when I try to wrap mine as per the example, I run into the problem of them being "hidden" from angularjs and it is unable to load them
page.html
<script type="text/javascript" src="my-module.js" %}"></script>
<script type="text/javascript" src="my-module-controller.js" %}"></script>
<div ng-app="my.app" ng-controller="MyAppController">
{{ somevar }}
</div>
my-app.js
(function() {
'use strict';
angular
.module('my.app', []);
});
my-app-controller.js
(function() {
'use strict';
angular
.module('my.app')
.controller('MyAppController', MyAppController);
function MyAppController() {
....
}
});
This results in the error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module my.app due to:
Error: [$injector:nomod] Module 'my.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.
If I remove the IIFE on the module declaration so I'm left with the following:
'use strict';
angular
.module('my.app', []);
It works, to the extent that the next error is:
Error: [ng:areq] Argument 'MyAppController' is not a function, got undefined
If I remove the IIEF from the controller definition, everything works as expected.
This is obviously a stripped down example, in the real project I am serving this page from a Django server, though I can't tell if that's relevant or not.

Those are not IIFE's. You are not invoking the function. End with }()); or })();
(function() {
'use strict';
angular
.module('my.app')
.controller('MyAppController', MyAppController);
function MyAppController() {
....
}
})();

Related

Karma: Error: [$injector:nomod] Module 'app' is not available

I am new to Angular World and very beginner at Karma.
I am receiving the following error when I am trying to run the Karma-Jasmine Unit test.
{
"message": "An error was thrown in afterAll\nUncaught 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.\nhttp://errors.angularjs.org/1.6.9/$injector/nomod?p0=app", "str": "An error was thrown in afterAll\nUncaught 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.\nhttp://errors.angularjs.org/1.6.9/$injector/nomod?p0=app"
}
Going through various posts, I found that this error occurs when:
Misspelled the module name
Forget to register the module
Forget to load dependencies
But it seems that none of the above issue applies to my app. My App is very small as of now. I am posting my almost whole app for reference.
Please find my code below for reference.
app.module.js
(function () {
"use strict";
angular
.module("app", [
"ngRoute",
"ngMessages",
"ngclipboard",
"ui.router"
])
.config(configurations);
function configurations($locationProvider, $routeProvider, $httpProvider) {
$locationProvider.hashPrefix("!");
$routeProvider
.when("/licensing", {
templateUrl: "app/licensing/licensing.html",
controller: "LicensingController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/licensing"
});
}
})();
index.html
<!-- Angular Libraries -->
<script src="./node_modules/angular/angular.js"></script>
<script src="./node_modules/angular-route/angular-route.js"></script>
<script src="./node_modules/angular-messages/angular-messages.js"></script>
<script src="./node_modules/#uirouter/angularjs/release/angular-ui-router.js"></script>
<script src="./scripts/clipboard.js"></script>
<script src="./libs/angular/angular-clipboard.js"></script>
<script src="./app/app.module.js"></script>
<!-- Controllers -->
<script src="./app/authentication/login.controller.js"></script>
<script src="./app/authentication/forgetpassword.controller.js"></script>
<script src="./app/licensing/licensing.controller.js"></script>
karma.conf.js
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// list of files / patterns to load in the browser
files: [
'./node_modules/angular/angular.js', // Angular Framework
'./node_modules/#uirouter/angularjs/release/angular-ui-router.js', // UI-Router
'./node_modules/angular-mocks/angular-mocks.js', // Loads the Module for Tests
'./app/licensing/licensing.controller.js', // Licensing Controller
'./app/app.module.js', // Our Angular App
'./app/licensing/licensing.controller.spec.js' // Licensing Controller Spec File
],
license.controller.js
(function () {
"use strict";
angular
.module("app")
.controller("LicensingController", LicensingController)
function LicensingController() {
// Some code
}
})();
licensing.controller.spec.js
describe("Licensing Form", function () {
var LicensingController;
beforeEach(angular.mock.module("app"));
beforeEach(inject(function (_LicensingController_) {
LicensingController = _LicensingController_;
}));
it("This is a Dummy Test for (2 + 2)", function () {
expect(2 + 2).toEqual(4);
});
});

Module is not available - Angular JS

I have installed angular-stripe and have included it in controller as follows
angular
.module('payments', [
"angular-stripe"
])
.config(function (stripeProvider) {
stripeProvider.setPublishableKey('my_key')
})
But the following error is thrown.
Module 'angular-stripe' 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.
(function (app) {
'use strict';
app.registerModule('payments');
}(ApplicationConfiguration));
You have to include this script in your application :
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
And angular-stripe.js :
<script src="npm-folder/angular-stripe.js"></script>
I hope this would help you!

Check $scope variable with jasmine return error

Currently trying to check very simple angular variables and functions. I cannot get even the simplest to work. This is my first time using it, and I need to use the older version as my lecturer requires it.
In the app.js I have many controllers but im only starting with one controller, with one variable assigned to a string:
var app = angular.module('myApp', ['ngRoute']);
blah blah blah etc etc
app.controller('HomeController', function ($scope) {
$scope.name = 'Batman';
}
In the runner.html file I have the following:
<script src="lib/jasmine-2.2.0/jasmine.js"></script>
<script src="lib/jasmine-2.2.0/jasmine-html.js"></script>
<script src="lib/jasmine-2.2.0/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src='https://code.angularjs.org/1.4.8/angular-mocks.js'></script>
<!-- include source files here... -->
<script src="../js/main.js"></script>
<!-- include spec files here... -->
<script src="spec/test.js"></script>
In the test.js i have the following:
describe('myApp', function () {
var scope, controller;
beforeEach(angular.mock.module('myApp'));
beforeEach(angular.mock.inject(function($controller,$rootScope){
scope = $rootScope.$new();
$controller('HomeController', {$scope: scope});
}));
it('sets the name', function () {
expect(scope.name).toBe('Batman');
});
});
I then get the following error when I run the test:
Error: [$injector:modulerr]
EDIT
It appears to be the angular routing causing the problem. When I removed the route module 'ngRoute' it appears to function correctly. Is there is method to using jasmine with routing?
The problem with this was you were not having angular-route library included despite having it as a module dependency (angular.module('myApp', ['ngRoute'])).
I added as the following along with other libraries:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-route.min.js"></script>
And it's working!
Here's working plunker

ocLazyload not loading the module

In html I am loading the oclazyload before my app.js -
<!-- inject:js -->
<script src="/packages/libs/jquery/dist/jquery.js"></script>
<script src="/packages/libs/angular/angular.js"></script>
<script src="/packages/libs/oclazyload/dist/ocLazyLoad.js"></script>
<script src="/packages/libs/angular-ui-router/release/angular-ui-router.js"></script>
<!-- endinject -->
<script src="app/app.js" ></script>
<script src="app/common/app.config.js" charset="utf-8"></script>
My app.js -
(function () {
angular.module('app', ['ui.router', 'oc.lazyload']);
angular.element(document).ready(function () {
angular.bootstrap(document, ["app"]);
});
})();
But for some reason it doesn't load the oc.lazyload module at all . what might be the problem ? Am I missing something ?
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module oc.lazyload due to:
Error: [$injector:nomod] Module 'oc.lazyload' 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.
There is a typo. The module name is camel case. Change
'oc.lazyload'
to
'oc.lazyLoad' //'L' capitalized
The dependency for oc lazyload should be added as oc.lazyLoad instead of oc.lazyload
app.js
(function () {
angular.module('app', ['ui.router', 'oc.lazyLoad']);
angular.element(document).ready(function () {
angular.bootstrap(document, ["app"]);
});
})();
Reference
I also had this error, even though I did not have any typos and I followed the configuration directions at https://oclazyload.readme.io/docs. I was using Angular within Ruby on Rails, and my error was fixed by adding the line below to my app/assets/javascripts/application.js file:
//= require oclazyload

Argument 'fn' is not a function, when trying to do unit test with Jasmine and AngularJS

I'm trying to do some unit tests with Jasmine in my Angular application, but I'm facing some errors.
Error
Error: [$injector:modulerr] Failed to instantiate module LocalStorageModule due to:
Error: [ng:areq] Argument 'fn' is not a function, got string
Spec
describe("testing the controller", function () {
var $controllerConstructor;
var scope;
beforeEach(module('app', ['ngRoute', 'LocalStorageModule']));
beforeEach(inject(function ($controller, $rootScope) {
$controllerConstructor = $controller;
scope = $rootScope.$new();
}));
it("should validate a contact", function () {
var ctrl = $controllerConstructor('crmContatosCtrl', { $scope: scope });
});
});
App.js
angular
.module('app', ['ngRoute', 'LocalStorageModule'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
// My routeProvider here
}]);
I'm not using neither Yeoman nor Karma yet, because this is my fisrt application using Angular.
Included Files
<script src="../../Scripts/jasmine/jasmine.js"></script>
<script src="../../Scripts/jasmine/jasmine-html.js"></script>
<script src="../../Scripts/jasmine/boot.js"></script>
<script src="../../Scripts/angular/angular.js"></script>
<script src="../../Scripts/angular/angular-mocks.js"></script>
<script src="../../Scripts/angular/angular-route.js"></script>
<script src="../../Scripts/angular/angular-local-storage.js"></script>
<script src="../../Scripts/ngStorage.js"></script>
<script src="../../Scripts/ng-infinite-scroll.js"></script>
<script src="../../Scripts/angular/common.js"></script>
<link href="../../Scripts/jasmine/jasmine.css" rel="stylesheet" />
<script src="../core/app.js"></script>
<script src="../crm/contatos.js"></script>
<script src="contatosSpec.js"></script>
I think you may simply have a problem with your configuration for the dependencies for the tests. Without Karma I don't know how you do the tests but I guess you have somewhere a configuration file for Jasmine where you specify the files to be included. You have to include all files and you have to include first all the libraries. Be careful with the order and try to respect the same as you have in your html file that you use to run the application.
If the order is wrong the JS will try to execute before the libraries it needs are included. In your case maybe even the whole angular stack.
Update
Do not forget that Jasmine works using it's own html file and will not include the libraries you usually use if you do not tell it. And also don't forget to include Angular Mock library , essential for your tests
Update 2
Ok I think I found why you have a problem
There is something wrong in this code
beforeEach(module('app', ['ngRoute', 'LocalStorageModule']));
In angular when you call a module using module('smthg',[]) you are creating it, not calling it. You should use this form instead, there is no need to reimport the services that you already included in your main module.
beforeEach(module('app'));
check the Creating versus Retrieval section of the angular documentation https://docs.angularjs.org/guide/module

Resources