How create wrapper for callback? - javascript

I use ajaxSubmit.
form.ajaxSubmit(successCallback);
I need create wrapper for successCallback.
How to do this?
I tried
form.ajaxSubmit(wrapperCallBack(successCallback));
var wrapperCallBack = function (successCallback) {
debugger;
changeState(false);
successCallback(this);
};

You're pretty close:
form.ajaxSubmit(wrapperCallBack(successCallback));
var wrapperCallBack = function (successCallback) {
return function() {
changeState(false);
return successCallback(this);
};
};
Or as I would prefer to write it:
form.ajaxSubmit(wrapperCallBack(successCallback));
function wrapperCallBack(successCallback) {
return function() {
changeState(false);
return successCallback(this);
};
}
There, wrapperCallback creates a function to wrap around its argument (the successCallback argument) and returns that function.
Both of those assume you're going to use wrapperCallBack to create wrappers more than once. If you only need a one-off, then you can just use an inline anonymous function:
form.ajaxSubmit(function() {
changeState(false);
return successCallback(this);
});

Related

self-executing anonymous functions and call it again

I want to do something like this:
var build= (function(){
//my function body
})();
function test(){
//somthing then call build
build() //i want to call build function again in my code
}
How can I do this?
I tried this in angular:
var buildRoot = (() => {
$SubNode.get({
TypeID: vendorAdminService.NodeType.Category
}, function(data: vendorAdminService.IGetNodeParameters) {
$scope.ProductTree = data.TreeNodeModelItem;
$scope.AjaxLoading = false;
}, function(err) {
// alert(err)
})
})();
$mdDialog.show(confirm).then(function() {
$Category.Remove(node.ID)
buildRoot
}, function() {
});
but it does not work.
Anybody can guide me??
You need to return a function in your IIFE.
If you IIF is not trivial and has many functionalities you could also consider using Reveal Module Pattern.
var build = (function() {
var f = function() {
console.log('hello');
};
f();
return f;
})();
function test() {
build();
}
test();
Just use a named function.
Your IIFE needs to return a function, for later calling. But then is no need for an anonymous function.
function build() {
//my function body
}
or
var build = function () {
//my function body
};
var build = (function() {
var init = function() {
// magic code
};
return {
init: init
}
}());
function test() {
build.init()
}
test();
You include all your functionalities inside your build object, and you'll be able to call them as soon as you return them from inside that object. This effectively is called the revealing module pattern
For more information, read this
I see that there are missing semi-colons ";"
$mdDialog.show(confirm).then(function() {
$Category.Remove(node.ID);
buildRoot();
}, function() {
});

JavaScript / jQuery scope

Hi I'm extending an existing plugin to use static JSON rather than load it from the server. This is a trimmed down version of the extension:
(function ($) {
$.fn.MyExtension = function (options) {
return this.each(function () {
if (opts.load_Json) {
$.get("", function (result) {
fromJson(opts.load_Json)
});
}
var fromJson = function (json) {
// json stuff..
}
});
});
If I remove the $.Get and call fromJson directly without the call back I get an error saying that fromJson is not defined. This must be some form of scope issue but I cant work it out?
This isn't scope. This is timing.
A function isn't assigned to fromJson until the end of the anonymous function you pass to each.
If you call it from your get callback, then that assignment will happen before the HTTP response comes back and the function fires.
If you call it directly, then it just doesn't exist yet.
Either reorder:
return this.each(function () {
var fromJson = function (json) {
// json stuff..
}
if (opts.load_Json) {
$.get("", function (result) {
fromJson(opts.load_Json)
});
}
});
Or use a function declaration (which will be subject to hoisting):
return this.each(function () {
if (opts.load_Json) {
$.get("", function (result) {
fromJson(opts.load_Json)
});
}
function fromJson (json) {
// json stuff..
}
});

Passing local functions to setTimeout()

I have written the following function.
function obj()
{
this.a;
}
obj.prototype.catch = function()
{
alert('Catched')
}
obj.prototype.do = function()
{
alert('called');
}
What i need is, to call obj::catch() after obj::do() is called and the call must be performed from inside obj::do()
So how to pass the local function of obj to setTimeout
i have tried
obj.prototype.do = function()
{
window.setTimeout('"'+this.catch+'()"',1000);
alert('called');
}
It does not worked
Then i tried
obj.prototype.do = function()
{
window.setTimeout('"'+this+'.catch()"',1000);
alert('called');
}
which gave me the following error on Chrome console
Uncaught SyntaxError: Unexpected token ILLEGAL
So i tried the following dirty method(is it really dirty ?)
obj.prototype.do = function()
{
this.pid = randomVal(100);
window['temp'+this.pid] = this;
window.setTimeout("temp"+this.pid+".catch();",1000);
alert('called');
}
function randomVal(bound)//returns a random number between 0 and <bound>
{
return (Math.floor(Math.random()*(bound)));
}
That worked.
so why the first two methods not worked.Is there any other way to do the same thing without global variables..
The second method and last method are almost similar .But why am i gettng the error in second method..?
The worked code can be found here
http://jsfiddle.net/jXhAs/
Don't pass strings to setTimeout … ever.
var self = this; // Because the scope will change
setTimeout(function () { self.catch() },1000);
Or if you are using JS 1.8.5:
setTimeout(this.catch.bind(this),1000);
You can read more about bind
You should pass a function to setTimeout (not a string):
Example:
var self = this;
setTimeout(function(){
self.catch();
},1000);
use a closure
obj.prototype.do = function()
{
window.setTimeout((function(that){
return function(){
that.catch();
};
})(this),1000);
alert('called');
}
Why go through all of this effort, just pass the function.
function obj() {
this.a;
}
obj.prototype.
catch = function() {
alert('Catched')
}
obj.prototype.do = function() {
setTimeout(this.
catch, 1000);
}
var test = new obj();
test.do();​

javascript - setTimeout return

How can I use setTimeout if I want to return a value
$.each(pCodes, function(index, pCode) {
setTimeout(func(parm1), 2000);
});
function func(in)
{
var value = 999;
return value;
}
First of all, your call to setTimeout is wrong. You are calling the function func and then using the result in the setTimeout method. Your code is equivalent to:
$.each(pCodes, function(index, pCode) {
var temp = func(parm1);
setTimeout(temp, 2000);
});
As func returns 999, you will be doing setTimeout(999, 2000), which of course doesn't make sense. To call a function that takes a parameter from setTimeout you need a function that makes that function call:
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1); }, 2000);
});
To handle the return value from func is a bit more complicated. As it's called later on, you have to handle the return value later on. Usually that is done with a callback method that is called when the return value is available:
var callback = function(value) {
// Here you can use the value.
};
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1, callback); }, 2000);
});
function func(in, callback) {
var value = 999;
callback(value);
}
First of all, make sure you pass to setTimeout a function, in your example you passed undefined to it, as you func(param1) executes func directly. What you want is something like this:
setTimeout(function() { func(parm1); }, 2000);
And for 'returning' the value: Use some kind of callback function that is executed with the value when timeout expired. Like so:
function callback(value) {
// doSomethingWithNewValue
}
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1, callback); }, 2000);
});
function func(in, callback)
{
var value = 999;
callback(value);
}
This is the general pattern used in such scenario (see event driven programming).
change it to :
var defValue;
$.each(pCodes, function(index, pCode) {
setTimeout(function(){defValue=func(parm1)}, 2000);
});
this way you can use the defValue in your function to access the returned value
It's pretty ugly, but you can use output parameters, since js objects are pass by reference:
function a() {
var param1 = 42;
var result = {};
b(param1, result);
}
function b(val, output) {
something();
output.returned = 4;
}
Or, you can use a callback (the better option):
function a() {
var param1 = 42;
b(param1, function (newVal) {
something();
});
}
function b(val, callback) {
//something
callback(4);
}
By the way, your call to setTimeout is wrong. setTimeout receives a function as a first parameter, and a delay as a second - the first argument is still seen as regular javascript code, so it evaluates it, so your setTimeout call turns out to be like this:
setTimeout(999, 2000);
Since you're returning 999 from the function.
However, setTimeout can also receive a list of arguments after the second parameter, so it can be turned into this:
setTimeout(func, 2000, param1);

Is there anything like return a function?

I have a requirement where I get the anchor tags id and based on the id I determine which function to execute.. so is there anything that suites below code
function treeItemClickHandler(id)
{
a=findDisplay(id);
a();
}
You can assign a function to a variable like so:
You can also return a function pointer from a function - see the return statement of findDisplay(id).
function treeItemClickHandler(id)
{
var a= findDisplay;
var other = a(id);
other();
}
function findDisplay(id)
{
return someOtherThing;
}
function someOtherThing()
{
}
Sure, functions are first class objects in JavaScript. For example, you can create a map (an object) which holds references to the functions you want to call:
var funcs = {
'id1': function(){...},
'id2': function(){...},
...
};
function treeItemClickHandler(id) {
if(id in funcs) {
funcs[id]();
}
}
As functions are treated as any other value, you can also return them from another function:
function findDisplay(id) {
// whatever logic here
var func = function() {};
return func;
}
functions are normal javascript values, so you can pass them around, (re)assign them to variables and use them as parameter values or return values for functions. Just use them ;) Your code is correct so far.
You can map between ids and functions to call in a number of ways.
One of the simpler ones is to create an object mapping ids to functions, and find the function to call from that object (this is in essence a nicer-looking switch statement).
Example:
function treeItemClickHandler(id)
{
var idMap = {
"some-id": findDisplay,
"another-id": doSomethingElse
};
if (!idMap.hasOwnProperty(id)) {
alert("Unknown id -- how to handle it?");
return;
}
// Call the corresponding function, passing the id
// This is necessary if multiple ids get handled by the same func
(idMap[id])(id);
}
function findDisplay(id)
{
// ...
}
function doSomethingElse(id)
{
// ...
}

Categories