Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular module().factory() is not a function after concat (gulp)

Trying to concat/uglify my angular app using gulp for the last few hours, i have stripped down whole process to simple concat, and even removed angular file from concat process to a separate <script> request in header - and still, I receive the same error:

Uncaught TypeError: angular.module(...).factory(...) is not a function

Without concat everything is fine.

My gulp task:

gulp.task('JS', function() {
  gulp.src(['!_dependencies/angular.min.js', '_dependencies/jquery.min.js', '_dependencies/moment.min.js', 'Alpha/_lilhelpers.js', 'Alpha/routes.js' , '!trainerreg.js', '**/*.js'], {cwd: './public/scripts'})         
    .pipe(concat('concat.js'))    
    .pipe(gulp.dest('./public/min'));
});

It seems that Error basicaly happends as soon as .factory appears in code.

Here is the line on which it currently stops with error - it is a minified code, yet i am not minifiying it, im just concating files right now including angular-animate.min from which this line of code (1st one in fact).
And if I remove angular-animate it will just throw error on another factory that will be on the way.

(function(N,f,W){'use strict';f.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(X,r,g){g=g.ngAnimateChildren;f.isString(g)&&0===g.length?r.data("$$ngAnimateChildren",!0):X.$watch(g,function(f){r.data("$$ngAnimateChildren",!!f)})}}).factory("$$animateReflow",["$$rAF","$document",function(f,r){var g=r[0].body;return function(r){return f(function(){r(g.offsetWidth)})}}]).config...

UPDATE: Oh, I was mistaken, it's NOT breaking as soon as .factory met; it breaks as soon as it meets .factory in minified part of concated file...

Will be happy to hear any solutions/assumptions!

like image 851
Max Yari Avatar asked Oct 01 '15 18:10

Max Yari


2 Answers

I've found it!
Chrome was pointing to a wrong line, Firefox helped me a bit. Error itself confused me, only after some time I understood that angular.module(...).factory(...) means not that .factory is undefined but rather that something trying to invoke returned by factory value as a function i.e .factory(...)() is happening. Today I finally figured out what was the cause. Right after one of my factories there was some 3rd party code (angular animate in this case) and it was wrapped in closure as usual, but the thing is, my factory had no ; at the end so after concat I had:

.factory('fact', function(){my-factory-code}) (function(args){3rd-party-code})()

Wrapping around closure was interpreted as function invocation due to a fact that line with factory wasn't terminated by semicolon. And this problem was not showing up without concat, as this module was in a separate file.

Lesson - don't forget our fellow ; ;)

like image 85
Max Yari Avatar answered Oct 26 '22 12:10

Max Yari


Without seeing your factory code, I'm assuming that you didn't claim your dependencies before your function... This has happened to me in the past. MAKE SURE THAT YOUR FACTORY IS SOMETHING LIKE THIS (and it is wrapped in an anonymous function):

 (function(){
  angular.module('yourModule')
    .factory('YourFactory', ["$scope", "$state", function ($scope, $state){
       //Your Code
    }]);
  }());

For Minified AngularJS Files, you need to claim your dependencies as strings in order for it to properly minify... and its always a good idea to wrap your controllers/factories/services in anonymous functions. I hope this helps.

like image 43
Robo Rick Avatar answered Oct 26 '22 13:10

Robo Rick