title: Angularjs app crashes with "Error: too much recursion" when defining a route
body: <p>I'm following this tutorial on using angularjs alongside laravel: <a href="http://angular-tips.com/blog/2014/11/working-with-laravel-plus-angular-part-2/" rel="nofollow">http://angular-tips.com/blog/2014/11/working-with-laravel-plus-angular-part-2/</a>. However, if I define a route in config.routes.js which points to a controller, any controller, my app crashes. In the console the error "Error: too much recursion" comes up, along with a useless stack trace. </p>
  
  <p>All my files are exactly the same as in the tutorial, I only changed the name of the route and the controller, but that shouldn't make a difference. </p>
  
  <p>I googled around a bit and it seems this error might be caused by using a wrong version of jquery. I use angularjs 1.3.0 and I have no idea which jquery version my app is using, but I used <code>npm install angular</code>, so it'd be weird if that installed a wrong version, right?</p>
  
  <p>I'm completely lost on why this happens and also very frustrated, so any help would be greatly appreciated. </p>
  
  <p>Thanks.</p>
  
  <p>EDIT: Added code:</p>
  
  <p>app/js/config.routes.js</p>
  
  <pre><code>angular.module('app').config(function($routeProvider, $locationProvider)
  {
      $locationProvider.html5Mode(true).hashPrefix('!');
  
      $routeProvider.when('/transactions', 
      {
          templateUrl: 'features/transactions/transactions.tpl.html',
          controller: 'Transactions'
      });
  });
  </code></pre>
  
  <p>app/js/transactions/transactions.js:</p>
  
  <pre><code>angular.module('app').controller('Transactions', function($scope, $http)
  {
      $http.get('/api/transactions').then(function(result) 
      {
          $scope.shows = result.data;
      });
  });
  </code></pre>
  
  <p>transactions.tpl.html is empty. </p>
  
  <p>app.js:</p>
  
  <pre><code>angular.module('app', ['ngRoute']);
  </code></pre>
  
  <p>EDIT 2: added gulp.js
  The only thing I changed here is, is that I added the 'webserver' task.</p>
  
  <pre><code>var gulp    = require('gulp');
  var fs      = require('fs');
  var plugins = require('gulp-load-plugins')();
  var es      = require('event-stream');
  var del     = require('del');
  
  var publicFolderPath = '../public';
  
  var paths = {
    appJavascript:     ['app/js/app.js', 'app/js/**/*.js'],
    appTemplates:      'app/js/**/*.tpl.html',
    appMainSass:       'app/scss/main.scss',
    appStyles:         'app/scss/**/*.scss',
    appImages:         'app/images/**/*',
    indexHtml:         'app/index.html',
    vendorJavascript:  ['vendor/js/angular.js', 'vendor/js/**/*.js'],
    vendorCss:         ['vendor/css/**/*.css'],
    finalAppJsPath:    '/js/app.js',
    finalAppCssPath:   '/css/app.css',
    specFolder:        ['spec/**/*_spec.js'],
    publicFolder:      publicFolderPath,
    publicJavascript:  publicFolderPath + '/js',
    publicAppJs:       publicFolderPath + '/js/app.js',
    publicCss:         publicFolderPath + '/css',
    publicImages:      publicFolderPath + '/images',
    publicIndex:       publicFolderPath + '/angular.html',
    publicJsManifest:  publicFolderPath + '/js/rev-manifest.json',
    publicCssManifest: publicFolderPath + '/css/rev-manifest.json'
  };
  
  gulp.task('scripts-dev', function() {
    return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
      .pipe(plugins.if(/html$/, buildTemplates()))
      .pipe(plugins.sourcemaps.init())
      .pipe(plugins.concat('app.js'))
      .pipe(plugins.sourcemaps.write('.'))
      .pipe(gulp.dest(paths.publicJavascript));
  });
  gulp.task('scripts-prod', function() {
    return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
      .pipe(plugins.if(/html$/, buildTemplates()))
      .pipe(plugins.concat('app.js'))
      .pipe(plugins.ngAnnotate())
      .pipe(plugins.uglify())
      .pipe(plugins.rev())
      .pipe(gulp.dest(paths.publicJavascript))
      .pipe(plugins.rev.manifest({path: 'rev-manifest.json'}))
      .pipe(gulp.dest(paths.publicJavascript));
  });
  
  gulp.task('styles-dev', function() {
    return gulp.src(paths.vendorCss.concat(paths.appMainSass))
      .pipe(plugins.if(/scss$/, plugins.sass()))
      .pipe(plugins.concat('app.css'))
      .pipe(gulp.dest(paths.publicCss));
  });
  
  gulp.task('styles-prod', function() {
    return gulp.src(paths.vendorCss.concat(paths.appMainSass))
      .pipe(plugins.if(/scss$/, plugins.sass()))
      .pipe(plugins.concat('app.css'))
      .pipe(plugins.minifyCss())
      .pipe(plugins.rev())
      .pipe(gulp.dest(paths.publicCss))
      .pipe(plugins.rev.manifest({path: 'rev-manifest.json'}))
      .pipe(gulp.dest(paths.publicCss));
  });
  
  gulp.task('images', function() {
    return gulp.src(paths.appImages)
      .pipe(gulp.dest(paths.publicImages));
  });
  
  gulp.task('indexHtml-dev', ['scripts-dev', 'styles-dev'], function() {
    var manifest = {
      js: paths.finalAppJsPath,
      css: paths.finalAppCssPath
    };
  
    return gulp.src(paths.indexHtml)
      .pipe(plugins.template({css: manifest['css'], js: manifest['js']}))
      .pipe(plugins.rename(paths.publicIndex))
      .pipe(gulp.dest(paths.publicFolder));
  });
  
  gulp.task('indexHtml-prod', ['scripts-prod', 'styles-prod'], function() {
    var jsManifest  = JSON.parse(fs.readFileSync(paths.publicJsManifest, 'utf8'));
    var cssManifest = JSON.parse(fs.readFileSync(paths.publicCssManifest, 'utf8'));
  
    var manifest = {
      js: '/js/' + jsManifest['app.js'],
      css: '/css/' + cssManifest['app.css']
    };
  
    return gulp.src(paths.indexHtml)
      .pipe(plugins.template({css: manifest['css'], js: manifest['js']}))
      .pipe(plugins.rename(paths.publicIndex))
      .pipe(gulp.dest(paths.publicFolder));
  });
  
  gulp.task('lint', function() {
    return gulp.src(paths.appJavascript.concat(paths.specFolder))
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter('jshint-stylish'));
  });
  
  gulp.task('testem', function() {
    return gulp.src(['']) // We don't need files, that is managed on testem.json
      .pipe(plugins.testem({
        configFile: 'testem.json'
      }));
  });
  
  gulp.task('clean', function(cb) {
    del([paths.publicJavascript, paths.publicImages, paths.publicCss, paths.publicIndex], {force: true}, cb);
  });
  
  gulp.task('watch', ['indexHtml-dev', 'images'], function() {
    gulp.watch(paths.appJavascript, ['lint', 'scripts-dev']);
    gulp.watch(paths.appTemplates, ['scripts-dev']);
    gulp.watch(paths.vendorJavascript, ['scripts-dev']);
    gulp.watch(paths.appImages, ['images-dev']);
    gulp.watch(paths.specFolder, ['lint']);
    gulp.watch(paths.indexHtml, ['indexHtml-dev']);
    gulp.watch(paths.appStyles, ['styles-dev']);
    gulp.watch(paths.vendorCss, ['styles-dev']);
  });
  
  gulp.task('webserver', ['indexHtml-dev', 'images-dev'], function() {
    plugins.connect.server({
      root: paths.tmpFolder,
      port: 5000,
      livereload: true,
      middleware: function(connect, o) {
        return [ (function() {
          var url = require('url');
          var proxy = require('proxy-middleware');
          var options = url.parse('http://localhost:8000/api');
          options.route = '/api';
          return proxy(options);
        })(), historyApiFallback ];
      }
    });
  });
  
  gulp.task('default', ['watch']);
  gulp.task('production', ['scripts-prod', 'styles-prod', 'images', 'indexHtml-prod']);
  
  function buildTemplates() {
    return es.pipeline(
      plugins.minifyHtml({
        empty: true,
        spare: true,
        quotes: true
      }),
      plugins.angularTemplatecache({
        module: 'app'
      })
    );
  }
  </code></pre>