Function inside the AngularJS Controller - javascript

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...})

Related

How can I set javascript function in global?

I want to set my function in global js. So it can called from anywhere
I have function this :
$(function () {
function formatCurrency(input) {
return input.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
}
});
I put the function on the
C:\xampp\htdocs\mysystem\resources\assets\js\main.js
And I add this : <script src="{{URL::asset('/resources/assets/js/main.js')}}"></script> on the
C:\xampp\htdocs\mysystem\resources\views\layouts\app.blade
When executed, on the console exist error like this :
GET http://mysystem.dev/resources/assets/js/main.js 404 (Not Found)
How can I solve it?
The issue seems to be you're using asset() wrong.
asset refers to a file in /public.
You should compile/minimize your JS for production and put it somewhere in /public, i.e. /public/js/my.js
You should define you function as a method of the window object.
window.formatCurrency = function(input) {
return input.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
}
Another more clean way it would be to define your function as a method of an object called Utils, like below:
var Utils = (function(){
function formatCurrency(input){
return input.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
}
return {
formatCurrency: formatCurrency
}
}());
Doing so, you will not pollute the global namespace. You will have only one variable defined in the global namespace called Util, which would contain an obejct with useful functions that can be used by other parts of your application. As it is you can't see the benefits of the latter approach. However you can consider how it would be if you wanted to use 3 more functions, that by their own use 2 other functions as helpers. If that was the case your return statement would also contained the 3 more functions, whereas the 2 functions I mentioned before wouldn't be epxosed at all !
You can define global function like this
window.formatCurrency = function(input){
return input.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
}
and you are define function in ready function($(function)) then you must call this in ready function also. So better define it outside of ready function or in self invoking function.

What is the correct way of calling an internal function using the module pattern in Javascript

I am new to Javascript and am still getting my head round the various ways of creating objects i.e constructor+new, prototypal, functional & parts.
I have created what I think is an object factory using the module pattern and want to know what the correct method of calling an internal method would be. Is it via this or function name.
Here is my module:
function chart() {
function my() {
// generate chart here, using `width` and `height`
}
my.sayHi = function(){
console.log('hi');
my.sayBye();
};
my.sayBye = function(){
console.log('Bye');
};
return my;
}
var test = chart();
test.sayHi();
You can see that the first function calls the second using my.sayBye() or is it better to use this.sayBye(). Both produce the same result and run without error.
The module pattern allows you to dispense with the 'this' variable if you want to. I would probably rewrite the above code to look like this and then the question becomes moot.
function chart() {
var hiCount = 0;
function sayHi(){
console.log('hi');
hiCount++;
sayBye();
};
function sayBye(){
console.log('Bye');
};
return {
sayHi : sayHi,
sayBye: sayBye
};
}
var test = chart();
test.sayHi();
In the above code all is defined within the function chart. As JavaScript's scope is at the function level every time the chart function is called a new set of functions will be defined. And a new set of variables can also be defined that are private to the function as they are defined in the function and are not accessible from outside. I added hiCount as an example of how you could do this. The Module pattern allows privacy in JavaScript. It eats more memory than the prototype pattern though as each time a function is declared it is not shared between other instances of the same class. That is the price you have to pay in Javascript to have class variables that are private. I willingly pay it. Removing 'this' from my code makes it easier to understand and less likely that I will fall into problems of misplaced scope.
Using "this" is better approach because you would be able to bind the function directly to the parent function object.And you dont need to return anything from the function.
where as in your case you are explicitly returning another function
Here is the use of "this" approach
function chart() {
this.sayHi = function(){
console.log('hi');
}
}
var test = new chart();
test.sayHi();
Using this approach you would be able to call anything in the prototype of function "chart"
Eg
chart.prototype.hello = function(){
console.log('hello')
}
So you would be able to call the hello function from the same object(test)

How do I make a nonexistent (non-member, non-global) method invocable without using eval?

Let's start from the code:
function say(name) {
var ghost=function () {
function ghost() {
alert('!');
};
return body;
};
eval("var body=''+"+name+';');
eval(name+('=('+ghost).replace('body', body)+')();');
eval(name+'();');
}
function Baal() {
if ('undefined'===typeof ghost) {
say('Baal');
return;
}
ghost();
}
say('Baal'); // or just Baal();
Looks like that saying the devil's name invoke his presence (well, maybe he needs somebody for spiritual possession) ..
As you can see the ghost doesn't exist along with Baal, but we can invoke it since there're evals in say(name).
say(name) reassigns Baal to its code body as a closure and makes it captured a ghost method, that's how things work. But I'm trying to avoid eval ..
So .. let me reword the question:
How do I make a nonexistent(and not a member or global) method invocable without using eval?
Let me rephrase your question, just to make sure I’ve got it. Given a function, you want to put a new variable in its scope, without that scope being the global scope or a scope shared between the caller and the subject, without using eval (or the equivalent new Function and other hacks depending on the environment).
You can’t.
In the case you just mentioned, you could define one function, base(), that uses arguments.callee.caller.
Don’t do that.
The short answer: You don't.
That scope is not available. If you were to attach the scope then it would be available inside of the scope used. You could then access the method handles. I assume this is not what you were looking for, but here is what that would look like. demo
function say(name){
var methods = {};
methods.Baal = function(){
alert("!");
};
return methods[name];//this could invoke as well: methods[name]()
}
var handle = say('Baal');
handle();
What your evals break down to is something along these lines (although with dynamic content from string building - this is the end result)
function say(name) {
var Baal = (function () {
function ghost() {
alert('!');
};
return function(){
if ('undefined'===typeof ghost) {
say('Baal');
return;
}
ghost();
}
})();
Baal();
}
say('Baal'); // or just Baal();
Note that the meat of what happens here is from the function Baal, namely that it calls a hardcoded ghost() which in turn calls a hardcoded alert. Why go through all of this trouble to access a hardcoded function?
A better way would be to inject this function as a callback which expects some parameters to be injected.
jsFiddle Demo
function say(callback){
var params = "!";
if( typeof callback == "function" ){
callback(params);
}
}
say(function(params){
alert(params);
});
It's very difficult for me to read through your code and figure out what you are trying to accomplish with it, but it appears that you are trying to introduce a variable into the current scope so that you can call it. You cannot do this in javascript with the method that you demonstrated. Scoping only ever "flows down". By that I mean that a variable or function defined within a function will only be available to that function and any other functions defined therein. Your function named ghost will only ever be available within the function where it is defined, regardless of when that function is evaluated.
What you can do, however, is write a function that returns a function. You can then call that function and assign the result to a variable in the scope where you want to expose functionality. Doing that would look something like this.
function defineSpecialAlert() {
return function(name) {
alert(name + "!");
};
}
var newlyDefinedMethod = defineSpecialAlert();
newlyDefinedMethod("Baal");
So if I understand, it seems like you want to create an alias of eval: Something like
#Note this code is not intended as a solution, but demonstrates
#an attempt that is guaranteed to fail.
#
function myAlias(ctx) {
eval.call(ctx, 'var ghost = 42');
}
myAlias(this);
alert(ghost);
Javascript allows many funky sleight-of-hand tricks especially with closures, but this is maybe the one impossible thing that javascript cannot do. I've tried at length to do this exact same thing, and I can tell you that you'll run into nothing but complaints from the browser, saying that eval cannot be re-contexted or aliased in any way.

Access a javascript variable from a function inside a variable

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.

Can someone explain the following piece of Javascript code?

I was reading another question, and I saw this:
var basketModule = (function() {
var basket = []; //private
return { //exposed to public
addItem: function(values) {
basket.push(values);
},
getItemCount: function() {
return basket.length;
},
getTotal: function(){
var q = this.getItemCount(),p=0;
while(q--){
p+= basket[q].price;
}
return p;
}
}
}());
Can you please explain why does he wrap the function in ( and )'s? Also, what is the purpose of that return? Couldn't he just write self.addItem = ... and so on?
When you wrap a function with parantheses, and add () to the end of it, it's a self executing function.
(function() x() {
//do something;
})();
And, by returning he's making basket variable somewhat private. Try getting basketModule.basket from anywhere else, and you'll get undefined.
That is called javascript Module Pattern. Defining a function and calling it immediately to prevent variables to be in the global space or to define a function name.
Note parentheses in the last line: (). The function is defined and immediately called:
(function() { })();
return { ... } returns an object having a method addItem
The intention of the code is to create an object with three methods. addItem,getItemCount and getTotal. They all depend on state represented by basket.
if basket was defined globally that state would be exposed (and there could only ever be one variable basket. both of those can lead to issues so by wrapping the entire declaration the state is encapsulated and only accessible from the created object.
There are other ways of achieving the same and the pro's and con's are related to style and how many objects of that particular type you're going to need.
wrapping the function(){}() is required since function(){}() will not parse

Categories

Resources