Unit testing an AngularJS app that uses $translatePartialLoaderProvider - javascript

I am designing the unit tests for an AngularJS web app, using Karma-Jasmine.
The web app uses angular-translate and, specifically, employs the $translatePartialLoaderProvider module. The app itself works well; however, the unit tests fail with the following error:
Error: [$injector:modulerr] Failed to instantiate module myApp.view1 due to:
[$injector:unpr] Unknown provider: $translatePartialLoaderProvider
I have followed the unit-testing instructions for angular-translate available at http://angular-translate.github.io/docs/#/guide/22_unit-testing-with-angular-translate, as mentioned in Question #18876290, yet the unit tests still fail with the above-mentioned error.
A code sample illustrating the error is available here (Plunker):
http://embed.plnkr.co/8X7diP/. Note that the app works well: you can switch views and the view text is translated as expected. As soon as you remove $translatePartialLoaderProvider in view1mod.js, the app passes the test.
Your help would be greatly appreciated!

Its because, even though your app.js has the translate dependency, your view1 or view2 modules don't, i.e. this will fix the spec -
angular.module('myApp.view1', ['ngRoute', 'pascalprecht.translate'])
You'll have to fix this in both view1mod.js and view2mod.js.

Related

Karma Error: [$injector:modulerr] Failed to instantiate module due to: (Index.html is working perfectly)

So I set up an angular js project in webstorm and everything works properly except for the karma testing suite
I am setting up the model as follows:
beforeEach(module('[modulename]'));
and my tests are:
it('should work', ((function() {
//spec body
expect(true).toBe(true);
})));
works and passes, but
it('should work, does it?', (inject(function(_$http_) {
//spec body
$http=_$http_;
expect(true).toBe(true);
})));
not only fails the test but suddenly my module is no longer loading :S
Error: [$injector:modulerr] Failed to instantiate [modulename] due to:
Error: [$injector:nomod] Module '[modulename]' 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.
why though even putting in both tests seems to work perfectly fine for the first test (without inject) - the second one still fails like previously stated...
IMPORTANT: everything works if I run my application in a browser window, so the error has to be in the test file or something :S
I'm rather new to angular js and karma so I hope this is not a stupid question.
Try using $httpBackend instead of $http. Also, injection and mocking should be done outside the test cases in the test setup phase. use beforeEach() block for any setup and instantiation code.

Minifying with Google Closure Compiler an AngularJs app written in Typescript

I've been writing an AngularJs app using Typescript in Visual Studio. Typescript compiles all files into a single file on build. We've added a post-build step on release for the google closure compiler to minify the single file output. Any option other than WHITESPACE_ONLY on --compilation_level parameter causes the application to fail to initialize. the nested module names for example of my.module.name { } become function(a){ function(a) { function (a) { when minified. this is causing an angular error when it's injecting in typescript the final injection entry is a "modulename.classname" reference. AngularJs fails to initiate this minified as it becomes a.classname. See below example of how it's written, and how it's minified.
myApp is in a my.module module, and the controller is in a sub-module called my.module.name
myApp.controller("myController", ["$scope", "myService", "myService2", name.myControllerClass]);
this works fine if we understand that myControllerClass is a class that's written as a controller, in the my.module.name module in a .ts file. (it's all referenced fine too, and works when not minified)
when minified with anything other than WHITESPACE_ONLY the output becomes:
(function(a){(function(a){var d=angular.module("MyModule",[]);
d.controller("myController", ["$scope", "myService", "myService2", a.myControllerClass]);
angular fails to initialise saying that a doesn't contain myControllerClass. It makes sense as a in this instance would be "my.module" not "my.module.name"
Has anyone come across this before and does anyone know a solution that allows minification past "WHITESPACE_ONLY" which is kind of not good enough for our situation. It doesn't have to be google closure compiler that is minifying, but minification of our typescripted angularJs application output is a necessity. It seems like a Typescript minification issue for how it outputs its namespaced module stuff, and then how a minifier interprets it but I'm not sure.
The angular framework provides a specialty directive that is designed to help identify potential issues with Dependency Injection: ng-strict-di.
Strict mode throws an error whenever a service tries to use implicit annotations.
Adding the ng-strict-di method to your bootstrap, either by including it with ng-app (<body ng-app="myApp" ng-strict-di>) or by setting strictDi: true when manually bootstrapping will enable strict mode.
Strict mode does not modify the code and is production safe. Using strict mode allows you to identify potential problem areas with dependency injection which are not minification safe.

$routeParams generating Unknown Provider

This is my code inside a Mean.IO package. The controller takes in a number from the URL and then passes it to a factory.
This bit of code is giving me and Unkown Provider error for $routeParams.
angular.module('mean.rotor-tablet').controller('taskListController',
function($scope,$location,$routeParams,dataFactory){
console.log("SAD");
$scope.partid=$routeParams.id;
$scope.part=dataFactory.getPart($scope.partid)
$scope.tasklist=dataFactory.getTaskList($scope.partid)
$scope.goToTask=function (task_index){
$location.path('task/'+$scope.partid+'/'+task_index);
}
})
The exact same code was working fine on an AngularJS application I was running on the LAMP stack. When I added this to Mean IO however I got this error. (in case it's important I created a new package and this is in a file called controllers.js in the controllers folder)
PS I'm a n00b to Mean.IO. The reason I chose to mention Mean.IO specifically is because the problem seems endemic to it and not to AngularJS in general

How to minify famous.angular without DI errors?

I'm running into some issues with famous-angular when minified.
A couple of the PRs I submitted yesterday were attempts to fix this, but these don't appear to have resolved the issue.
When built without minfication, everything works as expected.
When built with minification, but removing the dependency on 'famous.angular' from my app module,
the app degrades gracefully to angular only, so the layout is borked, but the underlying angular app works as expected, no errors.
When built with minification, and the app module depends on 'famous.angular',
the app does not load at all, with the following error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module famous.angular due to:
Error: [$injector:unpr] Unknown provider: t
http://errors.angularjs.org/1.2.23/$injector/u...<omitted>...2)
By employing this method,
I was able to determine which function was not getting minified correctly,
and tripping up Angular'S dependency injection:
function LocationHashbangInHtml5Url(appBase, hashPrefix) { /* ... */ }
This is in the core angular file - angular.js,
and it does indeed minify correctly in other instances.
So I am not sure why when I include 'famous.angular' in my app module,
this introduces the error.
Anyone know whaty is amiss here?
Demo of problem:
git clone git#github.com:bguiz/browserify-gulp-starter.git
cd browserify-gulp-starter
npm install famous
bower install --save angular angular-route famous-angular
# edit gulpoptions.js
# appName: 'app',
# appFolder: './src-famousangular/app/',
gulp serve-dist
I submitted these two PR's to famous-angular previously, thinking that I had caught all of the $inject scenarios:
https://github.com/Famous/famous-angular/pull/191
https://github.com/Famous/famous-angular/pull/190
Turns out that there was a third one that I had missed, and have now submitted a patch for:
https://github.com/Famous/famous-angular/pull/195
In my question above, I said function LocationHashbangInHtml5Url(appBase, hashPrefix) { /* ... */ } in angular/angular.js was the function that was not minifying correctly.
This was incorrect, and the culprit was in fact a provider in famous-angular/src/scripts/directives/fa-input.js.
For the curious, here is the process that I used to figure the above out.
As an added bonus, I happen to have discovered an additional technique to use when debugging dependency injection errors in minified AngularJs apps.
It turns out that the technique that I linked to above ( https://stackoverflow.com/a/25126490/194982 ) does not always work correctly.
What did work in the end, was to traverse up the execution stack, until we get to the invoke() function, as described in that technique. Then, instead of inspecting only fn, look in the Scope Variables tab in the the developer tools, and inspect every scope member which is a function.
This casts a wider net, and results in more things which need to be inspected;
but was necessary in this case, and I suspect might apply in others.

How to avoid or skip module load error in Angular.js?

//index.html
<html ng-app="app">
//app.js
angular.module('app', 'test-module')
If I don't register the test-module in any of my scripts like below:
angular.module('test-module', [])
I will get errors below in brower and the whole website will not be loaded:
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module test-module due to:
Error: [$injector:nomod] Module 'test-module' 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.
Q: How to ensure the website page will be loaded even through there are any unknown modules loaded errors ?
I think you should look on this problem from other side.
If you use test-module (module for testing) you in development process. You could configure your backend for work in several environments. For example dev, test and prod. You can handle sub domain and decide on backend which modules need to be loaded. dev.yourdomain.com (for dev environment), yourdomain.com (for production environment) and test.yourdomain.com (for tasting).
You can generate such script:
<script type="text/javascript">
var MyModules = ['test-module'];
</script>
And handle it so:
angular.module.apply(angular, 'app', MyModules);
I found solution to you answer :)
Angular have array of requires for each module, so you can easily push some requires if you want to use this module.
In your case you can do this
//index.html
<html ng-app="app">
//app.js
angular.module('app', [])
//test-module.js
angular.module('test-module', [])
angular.module('app').requires.push('test-module');
So if you load test-module.js to your browser, you automatically inject dependency to your app.

Categories