AngularJS 'unknown provider' after minification (ng-strict-di being activated) - angularjs

I first concatenate all my js files via grunt-contrib-concat grunt task. With this one everything worked fine (no minification).
I'm trying to switch to Google's Closure Compiler so I can minify it and add source maps, to start I'm using this options: --compilation_level WHITESPACE_ONLY and --formatting=pretty_print and I'm passing files in the same order as I did before with the grunt task so i should have a first output similar to what I've got before.
NOTE: Thanks to some sublime text magic and a diff checker, I have been able to check that both of my final generated files got all the same controllers/services in the EXACT SAME order.
All my controllers weren't using the annotation syntaxe (dependencies being declared as string before controller) so i used ng-annotate and this script to solve this problem.
Now all my files are ready for minification. To be sure about that I even declared ng-strict-di on my app and temporarly switch back to the previous concatenation system. It works perfect and fails if I deliberatly put a typo in my controllers name.
So from this I thought Closure Compiler should have worked like a charm... But no, I'm facing an Unknown Provider error when angular try to inject my first service inside my app.run() function. (The .config() is executed well as I've no custom dependencies here as well as the three first dependencies of the .run(). It really is MY personnaly implemented dependencie that fail.)
Did someone already face a similar issue ? Any idea what could cause this ?

Ok... I found out that closure compiler do not import files the same way as the grunt task I used to use.
When using the notation src/js/controllers/**/*.js I excpected it to import the files directly inside my controller folder but it didn't.
I was sure to have checked this but I certainly made a mistake and compare the old file with the old file instead of the new one; that's why I thought I got all my dependencies in the file and in same order when checking...

Related

Hybrid angular app throwing error "'./app.module.ajs.js' does not provide an export named 'default'"

I am attempting to convert my AngularJS project to run as a hybrid (i.e. 1.x alongside 2+) following the bootstrapping steps provided at the angular.io guide page provided specifically for the task. I have followed the guide with some modifications (primarily just so that I could maintain my existing project structure). My steps in inexact order have been to
include webpack
convert my original app.module.js and all angular modules declared therein to exportable ES modules
(app.module.js became app.module.ajs.ts, which is transpiled to .js)
add a new app.module.ts for manual bootstrapping, as per the docs (looks identical to the file of the same name in the docs) and remove the ng-app directive from the html as it is no longer necessary
import the modules into all dependent controller, direcive and service files.
Now when I serve the project, which I believe is the step I should be on (the steps seemed pretty straightforward...) I get a slew of the same error:
However when I open that file up, I do actually see exports.default = ariaApp.
Also, the .ts file by the same name does indeed contain the declaration and the default export
const ariaApp = angular.module("ariaApp", [])
export default ariaApp;
Has anyone seen this before? / Does anyone know what this error indicates? It seems totally off... All suggestions appreciated! Thank you!!

How to stop WebStorm from warning about "unused methods" that are only invoked in the template file?

Is there a way for WebStorm to "see" the methods in my HTML and link them with their respective component class?
Details
I usually write my component controller in one file and the component template (html) in another file.
When I do this, methods that are only used in the template are marked as "unused" by WebStorm, and they throw a warning.
For example, in the component ctrl I have a handleViewChange() method.
In the template file I have vm.handleViewChange();
WebStorm warns me that handleViewChange is an unused method even though I have used it in the template.
Please note: I am aware that I can suppress the warn for this particular statement. I would rather WebStorm recognized the method is actually used.
Particularly relevant with refactor-happy colleagues (or refactor-happy future me).
Edit #1
I have already enabled the AngularJS library in Webstorm settings, but it does not fix this particular issues.
Downloading angular TypeScript community stubs per suggestion at this post doesn't enable AngularJS support for your project.
You need to have angular.js file (debug version, uncompressed!) in your project (either in your project directory or configured as JavaScript library) - normally it's enough to get Angular directives/methods recognized. See http://blog.jetbrains.com/webstorm/2014/03/angularjs-workflow-in-webstorm/, 'Include angular.js in Your Project' section.

Angular "TypeError: b is undefined" when using uglify

I'm using Angular, and as you know, there is Angular "1" (the old version) and Angular 2 (the newest) which include typescript.
This is my problem I've encountered today:
I'm doing an application using angular, so I've created the project folder (project-frontend) and installed locally grunt, with bower I've downloaded the packages for angular.
I've created the gruntfile.js and configured it with these tasks:
"grunt-contrib-concat": "^1.0.1"
"grunt-ng-annotate": "^2.0.2"
"grunt-contrib-uglify": "^2.0.2"
And with many others, like cssmin, htmlmin etc etc, but the problems occours with these tasks, or, precisely with uglify.
The problem is that if I concat all angular js files (angular.js, angular-rout.js, angular-resource.js ...) and I uglify everything, then, when i deploy my war in a Tomcat, i get this error:
TypeError: b is undefined
So, what i think that cause the problem is uglify, because I've tried to run the same tasks for another old project, which was having uglify 1.0.1 and everything works, I've also controlled that if I just run concat and ngAnnotate, the final angular files (the one from this project, and the one from the last) are pratically identical.
I don't know if this has to do something with typescript (seeing the error I thinked about that) because I assumed that typescript have been inserted into angular since 2.0.0 versions, and I'm currently working with a 1.5.8 version (I also tried 1.2.9).
I controlled my application code with jshint (it's the first task that i run) and there are no errors prompted in the terminal.
I've also tried to re-configure the tasks taking as example the old project Gruntfile.js file.
I don't know what to do anymore, I'm blocked with this problem and I don't know how to move further, some advices?
Ok, now that i've found the error, as i writed in the comments under my question, i figured out that concatenating js files like this:
src: 'bower_components/**/*.js'
Which should concatenate all js files inside folders and subfolders in my bower_components directory, simply don't know why but breaks angular final files, if i write
src: ['bower_components/angular/*.js',
'bower_components/angular-route/*.js',
'bower_components/angular-resource/*.js']
Which points directly to all files that need to be concatenated, everything works in my application with angular concatenated and uglified file
I don't know why there's this issue, beacuse if i print in terminal under my project-frontend folder this command:
echo bower_components/**/*.js
I can see this output:
bower_components/angular/angular.js bower_components/angular-resource/angular-resource.js bower_components/angular-route/angular-route.js
By the way this seems to be a solution to this type of problem, I hope this helps somebody in the future

Using Masonry with ReactJS in browser

https://github.com/eiriklv/react-masonry-mixin/blob/master/README.md
The above example shows the simple steps to get masonry-mixin working on node-js.
What solutions are available to enable my react component to use this plugin within a normal webpage? I would like a solution that has the least amount of 3rd party software to get working.
The require statement is not available without npm from what I understand.
Require statements can be used in client-side using a preprocessor called Browserify.
In order to use Browserify, you have to have one main .js file from which all your other files are loaded via require statements (however tangentially). You then run the Browserify command to parse and bundle it all into one file:
$ browserify main.js > bundle.js
I've personally used react-masonry-mixin, and this is the approach I use (although automated with Gulp).

Loading mocks into an AngularJS unit test

I'm trying to setup my AngularJS application to test out controllers, routes, templates and so on, but I'm having an issue getting some of the helper methods provided by the angular-mocks.js to work (namely module and inject).
I'm using testacular to load up the test suite with the following files added before the specs:
files = [
MOCHA,
MOCHA_ADAPTER,
'../application/lib/angular.min.js',
'./lib/angular/angular-mocks.js',
'./lib/angular/angular-scenario.js',
'../application/application.js',
'./lib/chai.js',
'./lib/chai-should.js',
'./lib/chai-expect.js',
'./spec/**/*.js'
];
So far so good, but when I run the tests I get this issue:
ReferenceError: Can't find variable: module
Not sure where this is loaded. Am I missing something?
First thing to check is that all those files are getting loaded in the test browser. It's surprisingly easy to get a path wrong in your config and not realize it. If you're running testacular with autowatch, you can navigate to http://localhost:9876/context.html with a browser and use developer tools inspect elements/resources/network and see if anything is missing.
If everything is good there and you're still having problems, post some of your test code and I'll take a look.
UPDATE: It appears (strangely) from the comments in the source for angular-mocks.js (line 1635) that window.module is only available with Jasmine. It looks like you're using Mocha instead of Jasmine. This is very likely the culprit.
ANSWER:
I can't rightly take credit for this Matsko, since you figured it out yourself... but it turns out that the current AngularJS stable download and angular-seed contain an older version of ngMock that doesn't support Mocha. Manually replacing the mock file with the latest from the github repo solves the problem. Glad I could help ;-)
I ran into this issue today and I wanted to provide others with a complete summary of the required steps to get this working. First let's say you have a module named myApp. Inside that that module there is a service called myModel. the myModel service has a method named getItems().
Currently, the angular-mocks.js (I am using AngularJS 1.0.6) does not support Mocha. You will need to visit this link and replace the 1.0.6 version with the one in the master branch from the AngularJS GitHub project. An easy way to do this (if you have wget) is wget https://raw.github.com/angular/angular.js/master/src/ngMock/angular-mocks.js in the correct directory. If you use a properly configured Sublime or vim it can also easily pull it down for you.
Make sure your karma.conf.js file includes the angular-mocks.js file in files array
Somewhere in your tests.js file (maybe at the top level describe) include beforeEach(module('myApp')); or whatever you named your main module.
If you plan to use the service (or whatever you want to include in the test) in more than one place you can call another beforeEach where needed like this:
beforeEach(inject(function(myModel) {
mymodel = myModel;
}));
otherwise you just can inject where it is needed. Now the mymodel variable (notice this is the variable you assigned in the beforeEach above) will be available to you for testing in your next blocks. For example, you can now write:
describe('when fetched', function() {
it('should return 3 items', function() {
// console.log(mymodel.getItems());
expect(mymodel.getItems()).to.have.length(3);
});
});

Resources