0

SOLVED:

Resolution here: https://stackoverflow.com/a/29662815/4004456

Batarang Chrome plugin was firing all ng-click actions twice. Nothing wrong with my code.. Batarang owes me an afternoon...

NOTE: I have attempted all fixes in: Combating AngularJS executing controller twice

EDIT: something puzzling:

It seems all controllers are initialised twice, as it doesn't matter which view calls which function, it its fired twice, this is what lead me to believe it is a problem within the app.js file..

EDIT: resolutions I've attempted:

  • I've tried removing bower dependencies one by one to rule out a dependency causing it.
  • I've scoured my code for double controller init (both in index.html and then again in a div / bootstrap init. )
  • I've removed my custom directives one by one to ensure the "restrict:" / controller duplication isn't occurring.
  • I've removed all ng-if statements from the application.
  • Scoured all html for a duplicate ng-view / ui-view etc.
  • Tried all combinations of routes + links having and not having trailing slashes.

My issue however is nearly identical to the above question, my controllers are firing functions twice on button click.

I've tried to set up a plunkr but the code is too complex for me to get it working properly.. I've stripped any bloat out of the below code. index.html

<section ng-show="!stateIsLoading"> <div ng-view></div></section>
<section class="colorful" ng-hide="!stateIsLoading">
    <three-bounce-spinner></three-bounce-spinner>
</section>

app.js

    'use strict';

/**
 * @ngdoc overview
 * @name smcmsApp
 * @description
 * # smcmsApp
 *
 * Main module of the application.
 */
angular
    .module('smcmsApp', [
    'ngAnimate',
    'ngAria',
    'ngCookies',
    'ngMessages',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.bootstrap',
    'angular-spinkit',
    'restangular'
  ])
    .config(function ($routeProvider, RestangularProvider) {
        $routeProvider
            .when('/', {
                templateUrl: 'views/main.html',
                controller: 'MainCtrl'
            })
            .when('/about', {
                templateUrl: 'views/about.html',
                controller: 'AboutCtrl'
            })
            .when('/sales', {
                templateUrl: 'views/sales.html',
                controller: 'SalesCtrl',
                resolve: {
                    mailers: function (API) {
                        return API.mailers.getList();
                    },
                    totals: function (Restangular) {
                        return Restangular.all('profit').customGET();
                    }
                }
            })
            .when('/design', {
                templateUrl: 'views/design.html',
                controller: 'DesignCtrl',
                resolve: {
                    design: function (API) {
                        return API.design.getList();
                    }
                }
            })
            .otherwise({
                redirectTo: '/'
            });
        RestangularProvider.setBaseUrl('http://localhost/SMCMS_Angular/api/Slim/');
    })
    .run(function ($rootScope, $log) {
        $rootScope.stateIsLoading = false;
        $rootScope.$on('$routeChangeStart', function () {
            console.log("route change start");
            $rootScope.stateIsLoading = true;
        });
        $rootScope.$on('$routeChangeSuccess', function () {
            console.log("route change success");
            $rootScope.stateIsLoading = false;
        });
        $rootScope.$on('$routeChangeError', function () {
            //catch error
            console.log("Route changing animation error");
        });
});

DesignCtrl.js

angular.module('smcmsApp')
    .controller('DesignCtrl', function ($scope, $log, design, Notifications, Data) {
        /* ------------------------- Order Interactions  --------------- */
        $scope.saveOrder = function (order) {
            Notifications.addAlert('error', 'called showModal() from design.js');
            $log.debug("called showModal() from design.js");
        };
});

views/design.html

<label ng-click="saveOrder(order)" class="btn btn-default">Save Details  <span class="glyphicon glyphicon-floppy-open"></span>
Community
  • 1
  • 1
Lewis
  • 624
  • 9
  • 16
  • Why do you think the problem arrises from these specific HTML-snippets? I think the way I would debug is: 1. Remove half of the application logic from the HTML. Still going wrong? 2. If not, you know the problem is in the removed part. Otherwise, remove another half from the remaining part. 3. Continue that way untill you know what goes wrong. – vrijdenker May 06 '15 at 16:00
  • Thanks for the trouble shooting advice, you may have overlooked my first note in the question, please see edit for details on already attempted troubleshooting. – Lewis May 07 '15 at 08:21
  • I'll add this to edit too but the reason I pinpointed it being the initialisation of the app is because ALL controllers in the app are active twice, it doesnt matter which controller / view invokes a function, it fires twice. – Lewis May 07 '15 at 08:34

1 Answers1

0

I believe the problem is in the way the app handles during initialization. If you navigate to your application http://example.com/ then your url will be an empty string and trigger the route change. After it fails to resolve it will then hit the otherwise and cause the double route change/initialization.

Basically if you fire up the route yourself upon load you shouldn't see the double change. You can just inject the $location service and direct there yourself inside of the run assuming you want to start at any one given point. (see the plunk: http://plnkr.co/edit/lTOSYX?p=preview )

.run(function ($rootScope, $log, $location) {
    $location.path('/');//Add this
    // continue code here
});

If your controllers are double loading then you probably have other complications such as the double controller declaration/execution issue mentioned in the note (Combating AngularJS executing controller twice).

Community
  • 1
  • 1
Matt
  • 1,013
  • 8
  • 16
  • Bravo on the .run double $log about route changing, if I navigate directly to a route within the app then the .run only fires once. However in ruling that out all I'm left with are the resolutions in the linked article which have all proven fruitless.. – Lewis May 07 '15 at 08:13
  • Please see edit in post as to the methods attempted already (which comprise all of the fixes suggested in linked question and other fixes from other questions) – Lewis May 07 '15 at 08:22
  • I'll add this to edit too but the reason I pinpointed it being the initialisation of the app is because ALL controllers in the app are active twice, it doesnt matter which controller / view invokes a function, it fires twice. – Lewis May 07 '15 at 08:34
  • Yup, glad to see you found a resolution :) – Matt May 07 '15 at 19:52