I have started learning AngularJS and while going through some code samples I came across the following:
(function(app) {
'use strict';
app.directive('sideBar', sideBar);
function sideBar() {
return {
restrict: 'E',
replace: true,
templateUrl: '/scripts/spa/layout/mypage.html'
}
}
})(angular.module('common.ui'));
The above code creates a custom directive using IIFE. I am very confused about the last line of the code. It is passing a module named common.ui. Can someone explain me how this way of passing a parameter works and how this can be rewritten in a different way?
angular.module('common.ui') becomes referenced by app. See What is the (function() { } )() construct in JavaScript?.
You can declare it normally
(function() {
var app = angular.module('common.ui');
})();
Without the final parens (passing the angular.module) it would just be a function that was defined but didn't do anything and it wouldn't be callable without a name. The parens are invoking it immediately.
As far as rewriting it could be defined with a name and then called. Because it would be called only once there is no need to give it a name. Instead it is just run.
There are other reasons to use IIFE (like closures for encapsulating data or getting around async code) but in this case it is really just avoiding naming and then calling.
the upper function isn't in the scope or being seen untile this () exist
which you are defining parameter to the upper function and call it .
Related
In AngularJS application inside a function which is again inside a Controller,
what will be best approach while creating a variable.
normally create with var keyword
function getAnswer() {
//Some code here
var persistedDateValue = templateFactory.getAnswer(ctrl.item.ItemId);
//Some other code here
return persistedDateValue;
}
add it to the controller scope
function getDateAnswer() {
//Some code here
ctrl.persistedDateValue = templateFactory.getAnswer(ctrl.item.ItemId);
//Some other code here
return ctrl.persistedDateValue;
}
Here ctrl is controller , like in Directive controllerAs: 'ctrl',.
My understating is that option one is better as we do not need this variable other then this function.
Please suggest.
I agree with ZSnake's answer, but if you do need to make this variable available in the rest of your controller on on the view then you will need
.controler('ControllerName', function() {
var _this = this;
function getDateAnswer() {
//Some code here
_this.persistedDateValue = templateFactory.getAnswer(ctrl.item.ItemId);
}
Best practice would be option 1, if, as you said, you're not going to use that variable elsewhere. That way you avoid having unused data on your scope.
Javascript is very permissive on this. If you were using a more strict language as C or any of it's variations you couldn't do what you expose in the second option.
This way of accessing variables form an outer scope (from outside the function) is called "closure" and could be helpful in some situations, but for sure not in the one you're exposing, that would only mess your code, since the function itself can return it's results by it's result stament in a "normal" fashion, maintaining one of the most important principles of the programming science: Separation of Concerns (SoC for friends)
So stick to option 1
I'm not sure which JavaScript design pattern I'm following. Can someone please help shed some light on it?
var masonrySupport = ({
large__videos__support: function() {
$('.masonry-container .largeRec').find('.itemMasVideo').parent().addClass('item_largeRec_video_height');
},
smallRec__videos__support: function() {
$('.masonry-container .smallRec').find('.itemMasVideo').parent().addClass('item_smallRec_video_height');
},
init: function() {
this.large__videos__support(),
this.smallRec__videos__support()
}
})
masonrySupport.init();
There are two "patterns" I can see here.
Using self invoking closure to isolate scope.
(function($) {
// Code here
})(jQuery);
Helps mitigate the creation of accidental global variables.
(Kind) the module pattern, where you create an object with a bunch of methods on it, and call init(). I prefer to self invoking closure version of it. The Revealing Module Pattern.
The pattern you are using is called the Module Pattern, and it is one of the most important patterns in JavaScript. You outer wrapper creates an anonymous scope that provides privacy and state to the code that you place inside it.
(function($) {
// Everything in here is private and stateful
// and we can access jQuery through the imported $ variable
})(jQuery);
To your scope, you're also passing the global jQuery object. This method is called global import, and is faster and clearer than accessing the implied global from within your scope.
Inside your scope, you are creating an API that is accessible through the masonrySupport variable, making it a Revealing Module Pattern.
I don't see this as a design pattern in the strict sense of terminology. May be associated with the module pattern, but it needs to return something to be accessible outside of it's inner scope. It's only a self executing function invoked inside a scope which in this case is jQuery. This is used in many jquery plugins. You isolate the scope of the self executing function to a specific - lets say - domain.
This can be found on the first declaration:
(function($) {
...
})(jQuery);
By closuring the function you are guarding the functions and variables declared inside the scope to a specific domain, in this way eliminating the possibility to accidentally override or redeclare some function or variable declared in the global scope. It's a common practice to isolate the scope from the global object which in Javascript world is the Object or on DOM context is window.
And it continues with the self executing function:
$(function() {
...
})
Effectively what is being done here is, once the document loads, execute two functions - 'large__videos__support' and 'smallRec__videos__support.'
Let's understand how it is being achieved,
Firstly it is Immediately-Invoked Function Expression (IIFE) in action. This pattern is often used when trying to avoid polluting the global namespace, because all the variables used in the function are not visible outside its scope.
(function($) {
...
})(jQuery);
Short hand of $( document ).ready() is being used. More here.
$(function() {
...
});
Thirdly, you are initializing one object being referenced by 'masonrySupport' and calling its method 'init.'
In JS, this is called and Immediately Invoked Function Expression (IIFE), and is known as the module pattern.
However in jQuery this pattern is used to create jQuery Plugins. I advise you to follow the best practices to make it work.
Check that jsfiddle to get you started.
Below the JS part:
(function( $ ) {
$.fn.masonrySupport = function( option ) {
if ( option === "large") {
this.find('div.itemMasVideo').parent().addClass('item_largeRec_video_height');
}
if ( option === "small" ) {
this.find('div.itemMasVideo').parent().addClass('item_smallRec_video_height');
}
return this;
};
}( jQuery ));
$( 'div.masonry-container.largeRec' ).masonrySupport( "large" );
I see some code snippet as below while learning the Javascript, I am not sure about it, could you please advise what this structure exactly does, and when to use?
(function abc()
{
//action code here
})();
example
(function test() {
alert(1);
})();
Thank you much.
The best you can do is to read this article:
JavaScript Module Pattern: In-Depth
Smalle cite:
Anonymous Closures
This is the fundamental construct that makes it all possible, and really is the single best feature of JavaScript. We’ll simply create an anonymous function, and execute it immediately. All of the code that runs inside the function lives in a closure, which provides privacy and state throughout the lifetime of our application.
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());
But really go through this article and observe what we do have, thanks to others, who described JS patterns for us...
Because the more imprtant piece is the MODULE pattern
Module Export
Sometimes you don’t just want to use globals, but you want to declare them. We can easily do this by exporting them, using the anonymous function’s return value. Doing so will complete the basic module pattern, so here’s a complete example:
var MODULE = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
I have code snippet in which there is a Angular Modular Controller, but there is a function inside the same controller and with a call, which is raising doubt in my mind that is this way of coding allowed in Javascript or Angular? If Yes then how does it read it? See the below code format I have:
obj.controller('CartController',function($scope){
$scope.totalCart = function(){
var total = 10;
return total;
}
function calculate(){
...Some Logic..
}
$scope.$watch($scope.totalCart, calculate);
)};
Please help me to understand that is this type of function definition and call within a controller allowed in Angular/Javascript?
The calculate() is a private function -- it is only accessible in the scope of CartController. If you do not need to make use of your function in the view it is good idea to make it private. It says that it is not intended to be used in the view, so if someone else will be working with this code should think twice before use it in the view. Moreover: from within calculate you have access to all objects that are accessible in the scope of the CartController (including objects passed to CartController as parameters).
Function declared in this way is a proper JS function, which means you can get reference to it by its name. Sometimes it is thought to be more readable if you declare / create your function in advance and only then assign them to properties of some other object (in this case $scope):
function someFn (...) { ... }
function someOtherFn (...) { ... }
...
$scope.someFn = someFn
In the above snippet the intentions are very clear: make someFn accessible, while keep someOtherFn private.
Btw. declaring functions like: function nameFn(...){...} is called function statement; you can very similarly do it like: var nameFn = function(...) {...} (so called function expression). There is a slight difference between those -- basically it is illegal:
someFn();
var someFn = function(...) {...}
whereas, this works:
someFn();
function someFn(...) {...}
Sometimes you are forced to use this pattern, look e.g. at my answer to this question.
$scope.launch = function (which) {
};
var _func = function () {...}
The definition is allowed, it has the same affect as
$scope.$watch($scope.totalCart, function(){..some logic...})
Hello i have the following issue i am not quite sure how to search for it:
function(){
var sites;
var controller = {
list: function(){
sites = "some value";
}
}
}
So the question is how to access the sites variable from the top defined as
var sites
EDIT:
Here is a more complete part. i am Using marionette.js. i don't want to define the variable attached to the Module (code below) variable but keep it private to the Module, hope that makes sense. Here is the code that works:
Admin.module("Site", function(Module, App, Backbone, Marionette, $, _ ) {
Module.sites = null;
Module.Controller = {
list: function (id) {
Module.sites = App.request("site:entities");
}
};
});
and i would like instead of
Module.sites=null;
to do
var sites;
That sort of thing does make a difference right? Because in the first case i would be defining an accessible variable from outside where as the second case it would be a private one. i am a bit new to javascript so please try to make it simple.
if you are looking for global access, just declare the variable outside the function first, make your changes to the variable inside the function, then you can get the value whenever you need it.
I have found some info on this: sadly what i am trying to do doesn't seem possible.
Can I access a private variable of a Marionette module in a second definition of that module?
So i guess i have to do _variable to make developers know its private.
Disclaimer: I have no experience using Marionette, however, what you're describing sounds very doable.
One of the most powerful (in my opinion) features of JavaScript is closures. What this means is that any function declared from within another function has access to the variables declared in the outer function.
For example:
var func;
function foo() {
var answer = 42;
func = function () {
// I have access to variable answer from in here.
return answer++;
};
}
// By calling foo(), I will assign the function func that has access "answer"
foo();
// Now I can call the func() function and it has access to the "answer"
// variable even though it was in a scope that doesn't exist anymore.
// Outputs:
// 42
// 43
console.log(func());
console.log(func());
What this means is that if you declare var sites from within your module definition function as you described, you should have access to it from within any of your inner anonymous functions. The only exception is if Marionette is re-writing your functions (by using the Function function and toString()), which seems unlikely but possible.
Your original example should would as described, my suspicion is that there is something else going wrong with the code that is unrelated to your scope.