0

Is there any simple way to treat the arguments based on entity?

On my function all depends if the second param or third is a function, an object and so. This is my function:

function fbAPI(endpoint, param1, param2, param3, param4) {

    var type, params, success, error;

    if(typeof param1 !== 'function' && typeof param2 !== 'function')
    {
        type    = param1;
        params  = param2;
        success = param3;
        error   = param4;
    }

    if(typeof param1 === 'function')
    {
        type    = 'GET';
        params  = {};
        success = param1;
        error   = param2;
    }

    if(typeof param1 === 'object')
    {
        type    = 'GET';
        params  = param1;
        success = param2;
        error   = param3;
    }

    if(typeof param1 !== 'function' && typeof param2 === 'function')
    {
        type    = param1;
        params  = {};
        success = param2;
        error   = param3;
    }

    FB.api(
        endpoint,
        type,
        params,
        function (response) {

            if (response && !response.error) {
                /* handle the result */
                if(typeof success === 'function')
                    success(response);
            }

            if (response && response.error) {
                console.log(response.error);
                /* handle the result */
                if(typeof error === 'function')
                    error(response);
            }
        }
    );
}

Is there any way to make it shorter?

I should can call my function this way:

    this.api(_self.endPoints.friends, function (response) {
       //do something
    });

    this.api(_self.endPoints.friends, function (response) {
       //do something
    },function (response) {
       //do something
    });

    this.api(_self.endPoints.friends, 'GET', function (response) {
       //do something
    },function (response) {
       //do something
    });

    this.api(_self.endPoints.friends, {data: data}, function (response) {
       //do something
    },function (response) {
       //do something
    });

    this.api(_self.endPoints.friends, 'GET', {data: data}, function (response) {
       //do something
    },function (response) {
       //do something
    });
7
  • The only way to make it shorter that I can think of is to store data in a sane way Commented Jan 5, 2017 at 12:20
  • Consider having a main function with all arguments fixed and some supporting functions that will translate the possibilities to the main function. Commented Jan 5, 2017 at 12:21
  • Not sure if it is something you will encounter with your code, but what happens if param1 and param2 are both functions? Commented Jan 5, 2017 at 12:24
  • @Al.G. can you show me an small example? I am not sure if I fully understand. Loaf If param1 is a function param2 can be null or automatically a function. I updated the code with cases. Commented Jan 5, 2017 at 12:28
  • Don't design this type of function signature. It's a nightmare to handle, and it will also end up confusing your users. if you ever port this code to a typed environment like TypeScript, it will also be impossible to write a typed signature for. Commented Jan 5, 2017 at 12:38

5 Answers 5

2

Don't design this type of function signature. It's a nightmare to handle, and it will also end up confusing your users. You also will end up with odd situations where fbAPI(endpoint, 'GET', success, error) fails because you didn't think of defaulting params in the case that the type is given.

If you insist, then it's easier if you think of the arguments as an array that you shift things off the front of:

function fbAPI(endpoint, ...args) {

    var 
      type    = typeof args[0] === 'string' ? args.shift() : 'GET', 
      params  = typeof args[0] === 'object' ? args.shift() : {},
      success = args.shift(),
      error   = args.shift();
Sign up to request clarification or add additional context in comments.

3 Comments

So you would go for 1 parameter to be an object? function fbAPI({type: 'GET', params: {message: 'foo'}})
I was trying to copy the facebook model from here: connect.facebook.net/en_US/sdk/debug.js and search function api . Of course on their side it's more complicated.
I choosed your answer because is the shortest and simplest as I asked in question.
2

Maybe try something like this and decide what to do when calling your function

function example(opts) {
    // Do whatever you want with the options here
}


example({"type":"GET", "param":"[\"something\",\"here\",\"too\"]", "success":"yay", "error":"boo"});

Comments

1

The way You are doing it is a bit strange but You can use an array for that. Example:

var t = {
    // typeof param1
    'function': {
        // typeof param2
        'function': ['GET', param1, param2],
        'object': ['GET', param3, param2],
    },
    'object': {
        'function':['GET', param1, param3],
        'object': 'error',
    }
};


var r = t[typeof param1][typeof param2];

Hope it helps.

2 Comments

Whoa. What about if the first argument is a string?
What does :P mean? Anyway, who is supposed to check if r is not null? Why would it be null in any case when that's a valid signature he is supporting? In your code, if the first argument is a string, intended to be the type, then t[typeof param1] returns undefined, and then the access of [param2] causes a run-time error.
1

Because you're using JavaScript, I would avoid having multiple methods to call an internal method. That's called method overloading, and that is inherent to JavaScript unlike how it is in other languages like Java or C#.

There are a few ways you can do what you're looking for, though the way you have it is only verbose. One thing I would do is to make them if/else if/else statements instead of all ifs so that it is immediately recognizable that you can't go into multiples. I would also reorder so that they flow through a little logically.

var type, params, success, error;

if(typeof param1 === 'function') {
    type    = 'GET';
    params  = {};
    success = param1;
    error   = param2;
} else if(typeof param1 === 'object') {
    type    = 'GET';
    params  = param1;
    success = param2;
    error   = param3;
} else if(typeof param1 !== 'function' && typeof param2 === 'function') {
    type    = param1;
    params  = {};
    success = param2;
    error   = param3;
} else  if(typeof param1 !== 'function' && typeof param2 !== 'function') {
    type    = param1;
    params  = param2;
    success = param3;
    error   = param4;
}

However, you could also just use the arguments array to make things easier. You could also check the length of the array to ensure you at least have all of the parameters you're looking for.

function fbAPI(endpoint) {
    var type, params, success, error;

    if(typeof arguments[0] === 'function' && arguments.length === 2) {
        type    = 'GET';
        params  = {};
        success = arguments[0];
        error   = arguments[1];
    } else if(typeof param1 === 'object' && arguments.length === 3) {
        type    = 'GET';
        params  = arguments[0];
        success = arguments[1];
        error   = arguments[2];
    } else if(typeof param1 !== 'function' && typeof param2 === 'function' && arguments.length === 3) {
        type    = arguments[0];
        params  = {};
        success = arguments[1];
        error   = arguments[2];
    } else  if(typeof param1 !== 'function' && typeof param2 !== 'function' && arguments.length === 4) {
        type    = arguments[0];
        params  = arguments[1];
        success = arguments[2];
        error   = arguments[3];
    }
    // ... the rest of your function
}

Finally, what would probably work best is to have your parameter be an object, and let callers set up what they want.

function fbAPI(endpoint, settings) {
    var type = settings.type || 'GET';
    var params = settings.params || {};
    var success = settings.success;
    var error = settings.error;

    // Go about your business...
}

Comments

0

There are many ways to such things, find below 3 ways:

// Destructuring Assignment
function test1Fun ({ name, val }) {
  console.log(name, val);
}

// Extended Parameter Handling
function test2Fun (...params) {
  console.log(params.length);
  console.log(params[0]);
  console.log(params[1]);
  console.log(params[2]);
}

// Key-value
function test3Fun (options) {
  console.log(options.name);
}

var options = { name: "bar", val: 42 };
test1Fun(options);
test2Fun(1, 2, 3, 4, 5);
test3Fun(options);

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.