Index
Index

Reputation: 2381

JavaScript: Get parameters of passed function?

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

Answers (3)

apsillers
apsillers

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

Eric
Eric

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

Domenic
Domenic

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

Related Questions