Bungle
Bungle

Reputation: 19712

How do I include an argument based on a condition (in CoffeeScript/JavaScript)?

I've written a CoffeeScript function that resembles this contrived example:

my_func = (a, b, use_args = false) ->
  if use_args?
    other_func 'foo', a, b, 'bar'
  else
    other_func 'foo', 'bar'

This compiles to the following JavaScript:

var my_func;
my_func = function(a, b, use_args) {
  if (use_args == null) {
    use_args = false;
  }
  if (use_args != null) {
    return other_func('foo', a, b, 'bar');
  } else {
    return other_func('foo', 'bar');
  }
};

Is there a DRY approach to this function that would eliminate the duplicate call to other_func? Something like:

my_func = (a, b, use_args = false) ->
  other_func 'foo', a if use_args?, b if use_args?, 'bar'

but that's actually syntactically correct? Hopefully I'm not missing something obvious here. I'm not sure if CoffeeScript provides a handy way to do this, or if there's just a better JavaScript pattern I should be using.

Incidentally, I can't modify other_func to use different parameters, since it's actually _gaq.push(), part of the Google Analytics library that adds tracking information to a queue.

Upvotes: 1

Views: 273

Answers (3)

Leonid
Leonid

Reputation: 3171

var my_func = function(a, b, use_args) { 
  var args = []
  args.push('foo')
  use_args && args.push(a, b)
  args.push('bar')
  return other_func.apply(null, args)
}

Okay, no with from now on.

Upvotes: -1

Trevor Burnham
Trevor Burnham

Reputation: 77416

First off, I think the code in your original question is fine (other than the = false in the argument list—see my comment). It's perfectly efficient and readable. But if the repetition really bothers you, read on.

Chris is on the right track in his answer. Since this is CoffeeScript, there are some syntactic sugars you can take advantage of:

  • Instead of arr.splice(1, 0, [a, b]), you can write arr[1...1] = [a, b].

  • Instead of func.apply(null, arr), you can simply write func arr....

So, combining those, you can get your function down to 3 short, repetition-free lines:

my_func = (a, b, use_args) ->
  args = [foo, bar]
  args[1...1] = [a, b] if use_args
  other_func args...

Notice that you don't have to do a use_args? check; if it's null or undefined, it'll be coerced to false automatically (by JavaScript) for if use_args.

Upvotes: 2

Chris
Chris

Reputation: 10348

Use a combination of:

  • Array.splice() to inject the additional parameters in to an array of params, and
  • apply() to call the function with an array of parameters.

Here's a demo:

http://jsfiddle.net/ZSVtB/

Upvotes: 1

Related Questions