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

2

6

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!

Grappling answered 1/10, 2015 at 18:20 Comment(0)
G
11

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

Grappling answered 3/10, 2015 at 0:55 Comment(1)
Thanks mate! Probably saved me a couple of hours! :)Parsimony
P
3

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.

Pelfrey answered 1/10, 2015 at 18:45 Comment(1)
Thx for answer! thing is, as i have mentioned, i have stripped down procces to concat only, i.e no minification, and yes you are right im not claiming dependencies in this way, i now aware that it can cause problems on minifications, i suppose i will use some automated preparation plugin before minifications to add such a declaration. I will provide factory code on which it currently sops.Grappling

© 2022 - 2024 — McMap. All rights reserved.