3

so today i search over internet i found something interest. so normally i define the angular module like this

var app = angular.module('myApp',[]);
app.controller('myCtrl',function($scope){ 
//some code
})

or even like this

 angular.module('myApp',[])
    .controller('myCtrl',function($scope){ 
    //some code
    })

but today i found out there is a another way to define the angular module

(function(app){

})(angular.module('myApp',[]))

so what is the different between those initialization. is there most efficient way. i try to search this over the internet but could't find out a solution. thanks guys

Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80

4 Answers4

3

First & second declarations doesn't have any major difference. Third option is recommended.

  1. You are just saving the return value from angular module setter method and reusing it through a global variable.

  2. Instead of using a global variable for storing module reference, we directly declare controller on the returned value. This mode is called "method chaining"

  3. Here we making use of angular's getter syntax, which will return the module reference. Getter syntax together with an immediately invoked function expression (IIFE) makes sure that you are not polluting global namespace. And this is the preferred way of writing controllers, services etc.

For best practices in angular, have a look at John Papa's style guide for AngularJS

Aswin S
  • 254
  • 1
  • 4
2

The difference is in this:

var app = angular.module('myApp',[]);
app.controller('myCtrl',function($scope){ 
//some code
})

Here your app is a global variable.You have an access to the app from everywhere. You must avoid to create global variables.

This code also good.You don't have any global variables.Here you need to create you modul's components in one code line.So if you need then to have access to your module, you need to get it with angular.module('myApp').So this is a good variant, but not the best.

angular.module('myApp',[])
    .controller('myCtrl',function($scope){ 
    //some code
    })

For last

(function(app){

})(angular.module('myApp',[]))

This is the best variant. You are creating IIFE, which is - you create a function and invoke it immediately and pass the module as a parameter to it.The app now is visible only in the function and you don't pollute the global space.

What about in the performance - the last example will call an extra function, but first 2 will not, BUT here the one function's call will not affect on the performance.

Answer To the Comment:
Yes of course.

In the another file you can use like this

(function(app){

    })(angular.module('myApp'))

If you call angular.module('myApp') without the second parameter, it goes and tries to find module with the given name and if finds, returns the module.

Community
  • 1
  • 1
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • thanks @Suren Srapyan. i have my controllers in separate js files. so far i have used the 1st scenario. because in scenario 2 i have to define the same module again for each controller files. is there a way to separate js file using scenario 3 – Sachila Ranawaka Jul 05 '16 at 09:56
1

'Best' way to declare a module

As angular is on the global scope itself and modules are saved to its variable you can access modules via angular.module('mymod'):

// one file
// NOTE: the immediately invoked function expression 
// is used to exemplify different files and is not required
(function(){
   // declaring the module in one file / anonymous function
   // (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
   // which are very hard to dedect)
   angular.module('mymod', []);
})();


// another file and/or another anonymous function
(function(){   
 // using the function form of use-strict...
 "use strict";
  // accessing the module in another. 
  // this can be done by calling angular.module without the []-brackets
  angular.module('mymod')
    .controller('myctrl', ['dep1', function(dep1){
      //..
    }])

  // appending another service/controller/filter etc to the same module-call inside the same file
    .service('myservice', ['dep2', function(dep2){ 
    //... 
    }]);

  // you can of course use angular.module('mymod') here as well
  angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
      //..
  }])
})();

No other global variables are required.

Of course it depends all on preferences, but I think this is kind of the best practise, as

you don't have to pollute the global scope you can access your modules everywhere and sort them and their functions into different files at will you can use the function-form of "use strict"; the loading order of files does not matter as much Options for sorting your modules and files

This way of declaring and accessing modules makes you very flexible. You can sort modules via function-type (like described in another answer) or via route, e.g.:

/******** sorting by route **********/    
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...

How you sort it in the end is a matter of personal taste and the scale and type of the project. I personally like to group all files of a module inside of the same folder (ordered into sub-folders of directives, controllers, services and filters), including all different test-files, as it makes your modules more reusable. Thus in middle-sized projects I end up with a base-module, which includes all basic routes and their controllers, services, directives and more or less complex sub-modules, when I think they could be useful for other projects as well,e.g.:

/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...

angular.module('app', [
  'app.directives',
  'app.filters',
  'app.controllers',
  'app.services',
  'myMapSubModule'
]);

angular.module('myMapSubModule',[
   'myMapSubModule.controllers',
   'myMapSubModule.services',
   // only if they are specific to the module
   'myMapSubModule.directives',
   'myMapSubModule.filters'
]);

For very big projects, I sometimes end up grouping modules by routes, as described above or by some selected main routes or a even a combination of routes and some selected components, but it really depends.

EDIT: Just because it is related and I ran into that very recently again: Take good care that you create a module only once (by adding a second parameter to the angular.module-function). This will mess up your application and can be very hard to detect.

2015 EDIT on sorting modules: One and a half year of angular-experience later, I can add that the benefits from using differently named modules within your app are somewhat limited as AMD still does not really work well with Angular and services, directives and filters are globally available inside the angular context anyway (as exemplified here). There is still a semantic and structural benefit though and it might be helpful being able to include/ exclude a module with a single line of code commented in or out.

It also almost never makes much sense to separate sub-modules by type (eg. 'myMapSubModule.controllers') as they usually depend on each other.

Deepanjan
  • 649
  • 2
  • 8
  • 15
0

This type of function invoking is called immediately-invoked function. This provides an isolated scope and won't contaminate the global scope. For example, in the below code TestController is not available in the global scope.

(function(app){
   function TestContorller() {
   }

})(angular.module('myApp',[]))
Arun Ghosh
  • 7,634
  • 1
  • 26
  • 38