4

A similar question was asked here but it did not help me.

I am learning angularjs and I noticed the controller is executed twice.

I have a very simple fiddle example that shows the behavior here

I built the example as I was learning about services and at first I thought it was the injecting of the services into the controller but I commented all the code related to the services and still the controller is executed twice.

My example works but I am afraid I am doing something wrong.

<div ng-app="MyApp">
  <div ng-controller="MyCtrl">
    {{data1}} 
  </div>
</div>

var app = angular.module('MyApp', [])
app.service('Service1', function(){
  return {
    ajxResponse1: 'dataFromService1'
  };
 });

function MyCtrl($scope, Service1){
  alert('Entering MyCtrl');
  $scope.data1 = Service1.ajxResponse1;    
  alert('Exiting MyCtrl');
}
Community
  • 1
  • 1
user2223142
  • 119
  • 3
  • 8

4 Answers4

25

One possible source is this: if you are using Routing and specify the controller in routes - you must not specify it in template that the route uses. We had that problem when this was overlooked.

Ivan Koshelev
  • 3,830
  • 2
  • 30
  • 50
  • 1
    great shout, this was exactly the issue for me – iancrowther May 27 '14 at 10:35
  • Do you mean don't add `ng-controller=` inside of the template HTML? I'm having the same problem – Leon Gaban Oct 15 '14 at 14:43
  • ... but having ng-controller within the html element is a fundamental pattern of angular ... its usability is built around that type of notation (identifiers within elements) ... – dsdsdsdsd Mar 02 '16 at 18:54
  • @dsdsdsdsd When you specify a route, you already configure what is the controller used in the route, so there is no need to add `ng-controller` to the template (if you are adding the same controller). If you do this, the controller will be executed twice (one due to the route, another due to template). – Alisson Reinaldo Silva May 12 '17 at 11:50
4

Your controller was running twice in the fiddle because angular is referenced twice (once via the Frameworks & Extensions drop down and another as an External Resource).

See this updated fiddle where I removed the External Resource and the alerts only show up once.

The code remains unchanged:

function MyCtrl($scope, Service1, Service2, Service3){
    alert('Entering MyCtrl');
    $scope.data1 = Service1.ajxResponse1;
    $scope.data2 = Service2.ajxResponse2;
    $scope.data3 = Service3.ajxResponse3;
    alert('Exiting MyCtrl');
}
Gloopy
  • 37,767
  • 15
  • 103
  • 71
1

I had a similar problem and it was due to slashes in my routing.

I had something like /post{slug:[a-z0-9-]*/} for my route and when visiting the page at domain.com/post it would redirect to the version with a slash on the end.

Took me ages to work it out!

Edit: Actually, just took a more detailed look at your code and noticed there is no routing in there, so this is probably not the cause in your case.

Might be useful for people like me who were looking for a different solution though.

chrismacp
  • 3,834
  • 1
  • 30
  • 37
0

For all the people using rails and angularjs:

The rails framework that maps URLS to views and loads them clashes with the angularjs $route even when you have a single-view application.

To prevent the double-loading of your controller: go to application.js and remove "//= require turbolinks

You're welcome.

Achintya Ashok
  • 521
  • 4
  • 9