Reputation: 2381
As the title says I'm wondering if it's possible to get the parameters of a passed function. After hours of searching and looking at similar questions I'm still no closer, so I'll attach a simple example rather then what I'm working on - as I'm starting to suspect it's not possible.
Intended global function
function getTransaction(anyMethod)
{
db.transaction
(
function(transaction)
{
anyMethod(transaction);
},
function errorCB(err) {
redirectToLoginWithError("Error processing SQL");
},
function successCB() {
;//alert("Success!");
}
);
}
Functions to be called
function iWork(tx)
{
tx.doSomething();
}
function iDontWork(tx, param1, param2)
{
tx.doSomething(param1, param2);
}
Actual call
// Works fine
getTransaction(iWork);
// The problem
getTransaction(iDontWork, value1, value2);
getTransaction(iDontWork2, value1, value2, ..., valueX);
I've tried several different approaches, but none have proved successful so far. The closest (although not very) have been
getTransaction(function(){iDontWork(value1, value2)}));
This does call the correct function via the getTransaction, but does not pass the parameters correctly: Params (value1, value2) are kept, but the transaction object is lost / undefined. I can see why this does happen, but I cannot see any solution to it. All said, I'm also open to that the getTransaction should be scrapped and re-written somehow. The point is to get a flexible method that scales well.
Upvotes: 1
Views: 588
Reputation: 116030
Simply refactor getTransation
to take a function and an array of arguments. Prepend the transaction
variable to the argument array and call the function using apply
:
function getTransaction(anyMethod, methodArgs) {
var someFunction = anyMethod;
// if no args provided, use an empty array
methodArgs = methodArgs || [];
db.transaction (
function(transaction) {
// transaction is always the first arg; prepend it to the arg list
methodArgs.unshift(transaction);
// call method with argument array
anyMethod.apply(null, methodArgs);
},
// ...
);
}
Simply use it with:
doTransaction(iDontWork, [param1, param2]);
doTransaction(iWork);
EDIT:
As @rambo coder pointed out, you could just use regular arguments (instead of an array of arguments) by slicing arguments
:
function getTransaction(anyMethod) {
var someFunction = anyMethod;
db.transaction (
function(transaction) {
var methodArgs = arguments.slice(1);
methodArgs.unshift(transaction);
anyMethod.apply(null, methodArgs);
},
...
This way lets you supply arguments directly to getTransaction
, as you do in your example (doTransaction(iDontWork, param1, param2);
), instead of putting them in an array.
Upvotes: 1
Reputation: 97691
You can do it by creating partial functions:
function iDontWork(param1, param2){
return function(tx) {
tx.doSomething(param1, param2);
}
}
And:
getTransaction(iDontWork(value1, value2));
Upvotes: 0
Reputation: 112917
getTransaction(function (x) {
iDontWork(x, value1, value2);
});
Your getTransaction
assumes that its single argument is a function that takes one parameter. You need to create a new function that takes one parameter, but also includes the specific parameter values you want (namely value1
and value2
).
The above uses an anonymous function; you could also do it with a named function:
function forwarder(x) {
iDontWork(x, value1, value2);
}
getTransaction(forwarder);
Upvotes: 0