1

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.

1
  • Decided to scrap this solution as it's been pointed out that the getTransaction() is badly designed to begin with. Commented Jun 13, 2012 at 13:45

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

alternatively, this could have been made so that an array of args isn't required, as getTransaction(anyMethod) by slicing arguments
Thanks for your reply. But as far as I can work out this does not dynamically support none, one or more parameters / arguments. The idea is that getTransaction should be usable with any method that requires the transaction object.
My original answer and edited answer are functional equivalent. The only difference is that the original answer requires arguments to be wrapped in an array, while the edited answer allows you to use the exact syntax you specified in your "Actual call" section. Both answers support none, one, or many arguments (but in the original answer, the none/one/many arguments must be inside of an array, whereas the edited answer allows you place the none/one/many arguments directly as arguments to getTransaction).
Thank you for your reply. Although I decided to scrap the original solution due to the above and other limitations, I did find your answer helpful to help me understand the principle.
0
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);

2 Comments

Thanks for your reply. As far as I can work out this means that I'll have to create a matching "forward" method for any method that have more then one argument / parameter?
Yes; you have designed yourself into this corner, since your getTransaction function only works with functions of one argument, which is a very strange property.
0

You can do it by creating partial functions:

function iDontWork(param1, param2){
    return function(tx) {
        tx.doSomething(param1, param2);
    }
}

And:

getTransaction(iDontWork(value1, value2));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.