i got in one scope this function:
AjaxState.prototype.run_on_finish = function(callback){
if (this.isRunning()){
setTimeout('AjaxState.obj().run_on_finish('+callback+')', 250);
}else{
callback();
}
}
i just check if all ajax was finished and then after i call the callback (if all ajax is finished)...
but, at other point i try to use this function calling like this:
//.obj() is just to call the singleton patter.
function foo(){
var id = 2;
AjaxState.obj().run_on_finish(function(){
makeThings(id);
});
}();
when i execute this, i receive the msg "id is not defined" because i think that "run_on_finish" just look for it in global scope, if i remove "var" from id, it works... but i don't want to make it global, i want to send it throught the function, is that possible?
Try this:
function foo() {
var id = 2;
AjaxState.obj().run_on_finish(
(function(id) {
var sub_id = id;
return function() {
makeThings(id);
};
})(id));
}
http://jsfiddle.net/thomas4g/cGCBh/6/
Related
I just can't reach the function inside function using only HTML.
How to call setLayout() using only HTML or is it able to call only in Javascript?
<button onclick="customize.setLayout('b.html');">Click Please</button>
Javascript:
function customize() {
function setLayout(text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
}
}
It isn't possible to call setLayout at all.
Functions defined in other functions are scoped to that function. They can only be called by other code from within that scope.
If you want to to be able to call customize.setLayout then you must first create customize (which can be a function, but doesn't need to be) then you need to make setLayout a property of that object.
customize.setLayout = function setLayout(text) { /* yada yada */ };
Multiple ways to call a function within a function. First of all, the inner function isn't visible to the outside until you explicitly expose it Just one way would be:
function outerobj() {
this.innerfunc = function () { alert("hello world"); }
}
This defines an object but currently has no instance. You need to create one first:
var o = new outerobj();
o.innerfunc();
Another approach:
var outerobj = {
innerfunc : function () { alert("hello world"); }
};
This would define an object outerobj which can be used immediately:
outerobj.innerfunc();
if you insist to do it this way, maybe define setLayout and then call it,
something like this:
<script>
function customize(text, CallSetLayout) {
if (CallSetLayout) {
(function setLayout(text) {
//do something
alert(text);
})(text);
}
}
</script>
<button onclick="customize('sometext',true);">Click Please</button>
then you can decide if you even want to define and call setLayout from outside
Simple answer: You can't call setLayout() with this setup anywhere!
The reason being, setLayout() will not be visible outside of customize() not even from other JavaScript code because it is defined locally inside customize() so it has local scope which is only available inside customize(). Like others have mentioned there are other ways possible... (^__^)
You can return the response of setLayout() by returning it as a method of customize() and use it in your HTML like customize().setLayout('b.html'); e.g.
<button onclick="customize().setLayout('b.html');">Click Please</button>
JavaScript:
function customize() {
var setLayout = function (text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
};
return {
setLayout: setLayout
};
}
Another Approach
You can also define your main function i.e. customize as Immediately-Invoked Function Expression (IIFE). This way you can omit the parenthesis while calling its method in HTML section.
<button onclick="customize.setLayout('b.html');">Click Please</button>
JavaScript
var customize = (function () {
var setLayout = function (text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
};
return {
setLayout: setLayout
};
})();
You need to treat it as object and method
<button onclick="customize().setLayout('b.html');">Click Please</button>
Sorry I had to edit this code for more clarification
function customize() {
this.setLayout = function setLayout(text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
}
return this;
}
Just wondering if there is anyway to fire some code when a function is called, without adding the code to the function, for example:
function doSomething(){
//Do something
}
//Code to call when doSomething is called
You can wrap the function :
(function(){
var oldFunction = doSomething;
doSomething = function(){
// do something else
oldFunction.apply(this, arguments);
}
})();
I use an IIFE here just to avoid polluting the global namespace, it's accessory.
Well, yes, it's not actually hard to do. The crucial thing is that a function's name is just an identifier like any other. You can redefine it if you want to.
var oldFn = doSomething;
doSomething = function() {
// code to run before the old function
return oldFn.apply(this, arguments);
// code to run after the old function
};
NB that it's better to do oldFn.apply(this, arguments) rather than just oldFn. In many cases it won't matter, but it's possible that the context (i.e. the value of this inside the function) and the arguments are important. Using apply means they are passed on as if oldFn had been called directly.
What about something like:
function doSomething(){
doSomething.called = true;
}
//call?
doSomething();
if(doSomething.called) {
//Code to call when doSomething is called
}
I know you said you don't want to modify the original function, but consider adding a callback. Then you can execute code based on different results in your function (such as onSucess and onError):
function doSomething(onSuccess, onError){
try {
throw "this is an error";
if(onSuccess) {
onSuccess();
}
} catch(err) {
if(onError) {
onError(err);
}
}
}
Then, when you call doSomething, you can specify what you want done with inline functions:
doSomething(function() {
console.log("doSomething() success");
}, function(err) {
console.log("doSomething() error: " + err);
});
I have this following piece of code:
var stats = {
....,
checkExistance :
function(url){
var newUrl = url.substring(0, url.lastIndexOf("/")) + "/asyncCheckChartExistance";
var xhrObj = stats.getXhr();
var poolInterval = setInterval("poll()", 100);
function poll(){
xhrObj.open("GET", newUrl, true);
xhrObj.send(null);
xhrObj.onreadystatechange = function(){
if(xhrObj.readyState === 4 && xhrObj.status === 200){
if (xhrObj.responseText.length === true){
console.log("Exists!");
clearInterval(poolInterval);
} else {
console.log("Not Yet!");
}
}
}
}
},
}
I created the stats namespace. In this namespace I'm trying to create a function which polls the server every second. I should access this function this way: stats.checkExistance(myUrl).
However it seems that the setInterval function is not able to see the poll() function. I know that this is normal behavior taking in consideration that these are nested inside another function.
If I were to write this in the Global namespace there would be no problem but I'm interested to make this work in this kind of namespace. Any ideas? Thanks!
when you pass a string to setInterval, it runs in the global scope, by default, where poll would not be defined since it only exists in the scope of the checkExistance function.
To fix the issue, pass an anonymous function to setInterval instead:
var poolInterval = setInterval(function () {
poll();
}, 100);
Passing an anonymous function is usually the best idea as it allows you to write any javascript expressions/statements for the interval instead of just calling one function.
When you pass a string to setInterval, that string is interpreted as global code, and since poll is not a global function, a reference error is thrown.
However, you can pass a function reference instead of a string, and since the poll function is available in the scope in which the setInterval invocation is made, you can just write this:
var poolInterval = setInterval( poll, 100 );
var stat = {
say: function(name){
function doit(){
console.log(name);
}
setInterval(doit, 1000);
}
};
stat.say("hi");
A simple demo to show how. You will see "hi" every second.
I would like to be able to pass a parameter in a callback, but from the original calling function, and with the stipulation below, e.g. given:
function foo() {
var p = 5;
getDataFromServer(callBackFunction);
}
function callBackFunction(data) {
// I need value of 'p' here
...
}
function getDataFromServer(callback) {
// gets data from server
callback.call();
}
The catch is that I don't want to change the function getDataFromServer(), (i.e. allowing it to accept another parameter.)
Is this possible? Thanks.
Yes, and this is good to know.
function foo() {
var p = 5;
getDataFromServer(function(){
callBackFunction(p)
});
}
Yes, you could use a closure to do this.
However, it's hard to give code for this because your example isn't clear.
My guess is that you want something like this:
function foo() {
var p = 5;
getDataFromServer(callBackFunction(p));
}
function callBackFunction(p) {
var closureOverP = function(data) {... something with p ...};
return closureOverP;
}
So a simple anon function won't do?
function foo()
{
var p = 5;
getDataFromServer( function()
{
callBackFunction( p );
} );
}
It's Definitely possible and I would say good practice with functional programming languages. But you call the function like this:
function getDataFromServer(callback) {
// gets data from server
callback();
}
Is there anyway to calling a function from another function .. little hard to explain. heres in example. One function loads html page and when ready it calls the original function.
I think i need to pass in a reference but unsure how to do this... if i set it to "this" - it doesn't seem to work
ANy ideas?
order.prototype.printMe = function(){
order_resume.loadthis("myTestPage.html", "showData");
}
order.prototype.testme= function(){
alert("i have been called");
}
//Then when in "loadthis" need to call
orderRsume.prototype.loadthis= function(){
// DO SOME STUFF AND WHEN LOADS IT ARRIVES IN OnReady
}
order.prototype.OnReady= function(){
/// NEED TO CALL ORIGINAL "testme" in other function
}
It's not clear for me what you really want to do. In JS functions are first-class objects. So, you can pass function as a parameter to another function:
Cook("lobster",
"water",
function(x) { alert("pot " + x); });
order.somefunc = function(){
// do stuff
}
order.anotherone = function(func){
// do stuff and call function func
func();
}
order.anotherone(order.somefunc);
And if you need to refer to unnamed function from it's body, following syntax should work:
order.recursivefunc = function f(){
// you can use f only in this scope, afaik
f();
};
I slightly changed the signature of your loadthis function aloowing it to be passed the order to actually load.
I also assumed that your doSomeStuff function accepts a callback function. I assumed that it may be an AJAX call so this would be trivial to call a callback function at the end of the AJAX call. Comment this answer if you need more info on how to fire this callback function from your AJAX call.
order.prototype.printMe = function(){
order_resume.load(this, "myTestPage.html", "showData");
}
order.prototype.testme= function(){
alert("i have been called");
}
//Then when in "loadthis" need to call
orderRsume.prototype.load = function(order, page, action){
// DO SOME STUFF AND WHEN LOADS IT ARRIVES IN OnReady
doSomeStuff(page, action, function()
{
order.OnReady();
});
}
order.prototype.OnReady= function(){
/// NEED TO CALL ORIGINAL "testme" in other function
this.testme();
}