Is it wrong to define controller in angular wrapped in a function? - javascript

I am looking at some code, and I see that it is written as shown below. It doesn't make sense to me. Is it wrong? Why is it written like that? Also, shouldn't the use strict; go at the very top, outside of the code?
(function() {
'use strict';
angular.module('itemList', [])
.component('itemList', {
templateUrl: 'item-list/item-list.component.html',
controller: ['Item', ItemController]
});
function ItemController(Item) {
//code
}
}());

The reason it is wrapped in an IIFE is to keep all declarations like "use strict", functions and variables local to the scope contained within and not set in global namespace
If "use strict" was set global it can affect other unrelated code that my not comply and thus would cause unexpected errors to be thrown
Is it wrong to define controller in...
No. It is a best practice

It is an "immediately-invoked function expression". The main advantage is to make sure you don't pollute the global namespace when declaring local variable.
var someLeakingVar;
function foo(){
//do something with someLeakingVar.
}
The problem with the construct above is that any script coming after will be able to reach/modify someLeakingVar.
If you wrap it within the IIFE. You are sure, only the code within the expression is able to reac/modify it
(function(){
var nonLeakingVar = 'foo';
//...
})()
//here nonLeakingVar is undefined
In the same way as the 'use strict' statement can be function scoped, you make sure only the code within the IIFE will run in strict mode.
You can find more details:
strict mode
IIFE

Related

Should you use IIFE with RequireJS

It seems to be that if you are using RequireJS and you use define and require, then there is not point of using IIFE as well, since each module is already wrapped in a define/require. Is that the case?
In other words, does this code
define(['app'], function(app)
{
app.run();
});
has any difference/advantage to
(function() {
define(['app'], function(app)
{
app.run();
});
})();
Generally, you don't need to use an IIFE with RequireJS but sometimes you should.
If you use the usual define([... deps ...], function (...) {...}) format then you are only reading define from the global space and everything else you do is encapsulated inside the function you pass to define. With or without an IIFE, you can leak what you want to leak and keep private what you want to keep private.
The IIFE will typically be desirable if you are writing code that you want to be able to run with and without RequireJS. For instance, this:
(function () {
'use strict';
function factory () {
// Build our module...
return something;
}
if (typeof define === 'function' && define.amd)
define([], factory); // AMD environment: call define.
else
window.Foo = factory(); // Otherwise, leak into the global space.
})();
Popular libraries (e.g. jQuery) often have code like this that allows using them with RequireJS (or another AMD loader) and with script elements. This is extremely common. Using the IIFE allows to keep the factory function out of the global space.
The define() function is in Global scope anyway, so calling it inside an IIFE doesn't make a difference at all and it's kind of redundant.
It would be different if you put code outside of the define callback but you shouldn't do that because each file should represent an encapsulated module.
The only time I can think of using an IIFE with RequireJS might be when I'm configuring my application by calling require.config() before initialization; but even then if I'm just calling require.config() and don't have any code on the outside, I still wouldn't use an IIFE.
In this example here there wasn't a need to use an IIFE: https://github.com/vasilionjea/bower-requirejs-starter/blob/master/local/js/main.js
I hope that answers your question.

Namespace confusion with variable definition and module / revealing module patterns

I am just about to get the hang of this, but I still have one question
I have 2 modules contained in their own js files. One is based on the module pattern and the other the revealing module pattern. The confusion I have surrounds the assignment of a variable to these functions. The code below should help
Revealing module example. If I run this example I see a var1 variable in the global namespace with a doStuff public function
var var1 = (function() {
function doStuff() {
};
return {
doStuff : doStuff
}
})();
Module pattern example. If I run the example below in the debugger I can see the this.var2 line getting executed, but I do not see a var2 variable in the global namespace
(function() {
function doStuff() {
};
this.var2 = doStuff;
})();
Just wonder whether anyone can help explain what is most likely my misunderstanding.
Thanks

Nodejs: Wrapping entire script in a function call

I have been writing modules in nodejs as following :
module.exports = function (logger, db, external,constants) {
return {
//something
}
}
Recently someone in my team suggested that whole script should be wrapped in a function to avoid global confusion of variables i.e. like this :
(function () {
'use strict';
module.exports = function (logger, db, external,constants) {
return {
//something
}
}
}());
I understand that this practice is generally used at client side code. But during server side in nodejs is this required? I think that in nodejs there is really no global scope and only module.exports is the one which is accessible really irrespective of whatever we write in script file (ofcourse don't go wild over here).
No, IIFEs aren't required with Node.js.
They can be useful for any scripts that may be used in multiple environments (UMD).
But, each module/file executed by Node.js is given a "module scope," similar to the scope an IIFE provides, as described under "Globals":
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node this is different. The top-level scope is not the global scope; var something inside a Node module will be local to that module.
Though, there is still a global scope with Node.js. When a module creates a global, it will be accessible in other modules used by the same process.
foo = 'bar'; // lack of `var` defines a global
console.log(global.foo); // 'bar'
You're actually already doing this.
What he's suggesting is to wrap the entire script in a function like this:
function () {
}
That's all. Nothing special. Of course, in regular javascript a function definition just defines a function and the code inside the function doesn't run. So to automatically run the function you wrap it in an expression context and invoke it:
(function () {
})()
However, in node.js you don't need to do this. Instead you can simply call the function when you require the module. So in node.js, this does the exact same thing in terms of creating a private scope:
module.exports = function () {
}
So tell your friend you're already wrapping the entire script in a function.
This is perhaps the first case that I see the harm in naming things and design patterns. In this case your friend is thinking IIFE. But IIFE is nothing special. IIFE doesn't create a private scope. It's functions that create scope. IIFE is just a means for the function to call itself. Which is why I prefer calling it self-calling-function to avoid giving it a sense of magic which may cause some people to perceive it as something special.

"Controllers polluting the Global Namespace" what does it mean in Angular

I am newbie to Angular.js , i have read that Controllers should not pollute the global namespace.
What does it really means
and why angular.module('SomeApp',[]).controller('SomeController', function($scope) {})
is the best way to add a controller?
Edit: Polluting the global namespace is not specific to Angular, but to Javascript (and actually any dynamic-typed language, where variables could appear or be redeclared in almost any scope).
Polluting the global namespace would make unavailable -actually: will override- certain names among modules.
Imagine I have a module A in 'a.js' where I declare:
mymodule = angular.module('A');
function Foo($s, $http){ ... };
foo = mymodule.controller('foo', ['$scope', Foo]);
Also imagine I included, beforehand, a script named 'utils.js':
foo = 3;
foo in a.js would override foo in my utils script. That is polluting the global namespace and that's why it's a bad idea (perhaps I actually NEEDED the foo var).
Want to have code like that instead of chaining the calls? use a closure:
/* a.js */
(function(){
var mymodule = angular.module('A');
function Foo($s, $http){ ... };
var foo = mymodule.controller('foo', ['$scope', Foo]);
})();
And so, you will not pollute the global namespace since each declaration is inside the anonymous function call.
That format you used
angular.module('SomeApp',[]).controller('SomeController', function($scope) {})
does not pollute the global namespace.
This format would however:
Javascript
function UserController($scope) { ... }
HTML
<div ng-controller="UserController">
That is because the controller function is globally available outside of the scope of the angular application

Where to use 'use strict'; in revealing prototype pattern

I want to use 'use strict'; in revealing prototype pattern. The problem is that should I use it in constructor function or inside the prototype part in my below code
var Foo = function () {
'use strict'; // should I use it here
};
Foo.prototype = (function () {
'use strict'; // or should I use it here?
return {};
}());
It depends on your situation, but I think a good rule is to use it at the outermost scope you can. If you're working on a site (or a Node application) where you control all the code, put 'use strict'; at the top of every module. (With Node you can bypass that altogether by starting the runtime system in strict mode.)
If you have to deal with 3rd-party code that was written in 1997, you have to keep strict mode localized, but you can still cover your code with module-like anonymous function wrappers inside which everything is strict.
Note that 'use strict'; applies to its scope and all nested scopes. Thus:
(function() {
'use strict';
// hundreds and hundreds of functions etc.
})();
In that code, everything inside the outer anonymous function will be interpreted in strict mode.

Categories

Resources