I have recently start using angular, and I'm coding one of my first controllers like that:
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
function($scope, stakeholderViewFactory) {
$scope.users = [];
var loadUsersTable = (function(){
stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
success(function(data, status, headers, config) {
$scope.users = data;
}).
error(function(data, status, headers, config) {
//TODO: Alert
});
})();
}
]);
The thing is that I need the loadUsersTable to execute when the page loads, and I thought that using an inmmediatly invoked function could be the best and clearest option, but I can smell that this is not a good move for some reason that I don't know.
Maybe the best option is something like that, although you have to write more:
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
function($scope, stakeholderViewFactory) {
$scope.users = [];
var loadUsersTable = function(){
stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
success(function(data, status, headers, config) {
$scope.users = data;
}).
error(function(data, status, headers, config) {
//TODO: Alert
});
};
loadUsersTable();
}
]);
Could anyone point me the best practice to write this?
Thanks!
I have recently start using angular, and I'm coding one of my first controllers like that:
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
function($scope, stakeholderViewFactory) {
$scope.users = [];
var loadUsersTable = (function(){
stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
success(function(data, status, headers, config) {
$scope.users = data;
}).
error(function(data, status, headers, config) {
//TODO: Alert
});
})();
}
]);
The thing is that I need the loadUsersTable to execute when the page loads, and I thought that using an inmmediatly invoked function could be the best and clearest option, but I can smell that this is not a good move for some reason that I don't know.
Maybe the best option is something like that, although you have to write more:
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
function($scope, stakeholderViewFactory) {
$scope.users = [];
var loadUsersTable = function(){
stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
success(function(data, status, headers, config) {
$scope.users = data;
}).
error(function(data, status, headers, config) {
//TODO: Alert
});
};
loadUsersTable();
}
]);
Could anyone point me the best practice to write this?
Thanks!
Share Improve this question asked Feb 13, 2015 at 8:12 victorgb6victorgb6 912 silver badges10 bronze badges4 Answers
Reset to default 5The immediately executed function is a design-pattern (Javascript Module Pattern) mostly used to avoid leaking variables and privates into the outer scope (a function scope, not an Angular scope, just to be clear). In this case, you already have a controller function scope, so you don't need this syntax.
One best practice I encountered is the use of an initialize function, which is called at the end of the controller.
Advantages:
- The function name
init
clearly expresses what it does: run at the initialising of the controller; - You can clearly see all functions that are called.
- You can keep your code ordering as you like, grouped by functionality for example.
In your case it would look like:
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
function($scope, stakeholderViewFactory) {
var loadUsersTable;
$scope.users = [];
function init(){
loadUsersTable();
};
loadUsersTable = function(){
stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
success(function(data, status, headers, config) {
$scope.users = data;
}).
error(function(data, status, headers, config) {
//TODO: Alert
}
);
};
init();
}
]);
You don't need another function scope, the IIFE doesn't add anything here. Just put the code directly in the function:
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
function($scope, stakeholderViewFactory) {
$scope.users = [];
stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
success(function(data, status, headers, config) {
$scope.users = data;
}).
error(function(data, status, headers, config) {
//TODO: Alert
});
}
]);
Immediately-Invoked function doesn't have any binds with AngularJS! It is a JavaScript pattern, and depends on whether you NEED it or not.
Check some articles:
- http://benalman./news/2010/11/immediately-invoked-function-expression/
- http://esbueno.noahstokes./post/77292606977/self-executing-anonymous-functions-or-how-to-write
IIFE's are best practice as it prevents adding variables to global scope to prevent variable and function clashes. Your question talks about putting an IIFE inside a controller. Putting an IIFE in the controller doesn't really help as your controller isn't adding to global scope anyway and you shouldn't have many variables or functions added to the controller so the chance of having clashes is very small.
You could use an IIFE to wrap your controller, factories, directives as a good practice as they will prevent adding to global scope. For example the StakeholderViewController function won't be added to global scope:
(function() {
'use strict';
angular
.module('stakeholder')
.controller('StakeholderViewController', ['$scope','stakeholderViewFactory', StakeholderViewController]);
function StakeholderViewController($scope, stakeholderViewFactory) {
}
}();
There's some good information in John Papa's style guide.