Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I am new to angular js and currently stuck with very wired kind of a bug. function in a controllers runs twice when its called by view loaded against a route.

http://jsfiddle.net/4gwG3/5/

you will see alert twice!!

my view is simple

and my app code is following

var IB = angular.module('IB', []);    

//channel controller
IB.controller('channelsController', function ($scope, $routeParams) {
    $scope.greet = function () {
        alert('hi');
    };
});


IB.config(function ($routeProvider) {
    $routeProvider
    .when('/channels', {
        controller: 'channelsController',
        template: '{{greet()}}'
    })

    .otherwise({ redirectTo: '/channels' });

});
share|improve this question
    
need to read up on digest cycles... they can be called numerous times. Would help to explain what you want to acheive – charlietfl Oct 26 '13 at 17:06
up vote 24 down vote accepted

First check that you're not initializing your Angular app twice (by having it initialized automatically with ng-app).

One time I had 2 html pages with ng-app (one for login.html and another for main.html) and this was a problem I realized later.

Second and for me the most important, check if you have attached your controller to multiple elements. This is a common case if you are using routing.

In my case I was navigating to DashboardController like so:

app.config(function($routeProvider){
    $routeProvider
    .when('/', {
        controller: 'DashboardController',
        templateUrl: 'pages/dashboard.html'
    })
});

But I also had this in dashboard.html:

<section class="content" ng-controller="DashboardController">

Which was instructing AngularJS to digest my controller twice.

To solve it you have two ways:

removing ng-controller from your html file like this:

<section class="content">

or removing controller from routing (that is normally situated in app.js):

app.config(function($routeProvider){
$routeProvider
        .when('/', {
            templateUrl: 'pages/dashboard.html'
        })
    });
share|improve this answer
    
Face palm. Thank you so much for this. I had both the ng-controller and the controller initiated through app.js. +1 thanks so much Jorge – Robbie Smith Jan 3 at 22:35
    
Thanks. That is my problem. I add ng-controller to my html and also in my app.config, that is why all the functions got called twice. – Emmy Feb 24 at 0:07
    
yr Rock man. you've just saved my nerves )) – 7urkm3n Mar 21 at 21:03
    
Thanks. I had my ng-controller declared in my html as well as the app.config. – Coder Absolute Jun 17 at 15:34
    
Thanks. In my case error caused by the second issue listed above. – mablevj Oct 21 at 5:29

I think by creating an interpolation {{greet()}}, you create a watch on function greet. This function can get call as many time as digest cycle runs, so it is not a question about it running 1 or 2 times. So you should not depend upon the times the function is called.

share|improve this answer
1  
so can you please let me know how can a view call a function inside its controller. and when can controller call a function once view is loaded? – najam Oct 26 '13 at 17:16
    
You are already calling a function of controller inside view, and it is perfectly fine to do this. The only thing I am saying is you cannot depend upon how may times that function gets invoked. I did not understand your second part. I highly recommend you see the developer guide docs.angularjs.org/guide/concepts – Chandermani Oct 26 '13 at 17:20
    
I want view to request a function that is defined in controller just once? second way would be controller to know that view is loaded so he can call some functions that make expensive calls like loading a web player with live stream. – najam Oct 26 '13 at 17:28
    
@njam you need not wait for wait to load for view. You should move expensive call to the service method and use Promise api (docs.angularjs.org/api/ng.$q) to wait for service response. – Vijay Pande Oct 26 '13 at 17:44

I dont know what you are trying to achieve here. There are two alerts 1. When the controller is called. 2. When the template is get evaluated.

template is to provide the view part, however, in this case template is just evaluating function which is not creating any view.

share|improve this answer

I had the same problem, so I did:

$scope.init=function()
{
    if ($rootScope.shopInit==true) return;
    $rootScope.shopInit=true;
    ...
}
$scope.init();

Like if it were a singleton ! (I had many ajax calls each time I display, it was boring)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.