0

I am trying to add a class name to an element in react using this:

className: "btn btn-primary #{!@valid() ? 'disabled' : ''}"

However this is leading to class="btn btn-primary true"

This coffee code is compiled to the incorrect JS as follows:

className: "btn btn-primary " + ((ref = !this.valid()) != null ? ref : {
          'disabled': ''
        }),

What is the correct syntax of doing this in coffee?

Vipin Verma
  • 5,330
  • 11
  • 50
  • 92
  • 2
    CoffeeScript doesn't have a `? :` ternary, it uses `if x then y else z`. I don't know the context well enough but you might have problems with what `@` is when building that string too. – mu is too short Mar 18 '16 at 15:45
  • Yes, that totally works. Can you post this as an answer :) – Vipin Verma Mar 19 '16 at 07:15

1 Answers1

2

CoffeeScript doesn't have a C-style ?: ternary so this:

!@valid() ? 'disabled' : ''

is parsed as:

!@valid() ? ({ 'disabled' : '' })

which is an existential operator:

The Existential Operator

It's a little difficult to check for the existence of a variable in JavaScript. if (variable) ... comes close, but fails for zero, the empty string, and false. CoffeeScript's existential operator ? returns true unless a variable is null or undefined, which makes it analogous to Ruby's nil?

combined with an object literal. Hence the odd looking JavaScript you're seeing.

CoffeeScript uses if expressions instead of ?::

CoffeeScript can compile if statements into JavaScript expressions, using the ternary operator when possible, and closure wrapping otherwise. There is no explicit ternary statement in CoffeeScript — you simply use a regular if statement on a single line.

If you'd say this in JavaScript:

!this.valid() ? 'disabled' : ''

then you'd say this in CoffeeScript:

if !@valid() then 'disabled' else ''

and since "#{...}" works with an expression:

className: "btn btn-primary #{if @valid() then 'disabled' else ''}"
mu is too short
  • 426,620
  • 70
  • 833
  • 800