24

Hi i am trying to handle an ajax json response

here is my code

success: function (j) {     
    switch(true)
    {
        case (j.choice1):

            alert("choice2");
        break;
        case (j.choice2):
                alert("choice2");
        break;
        default:
            alert("default");
        break;
    }
}

based on what j is return i do my action BUT i keep getting the default.

I have alert the j values and come correct.Some how case (j.choice1) case (j.choice2) is not working.

I tried case (j.choice1!="") (j.choice2!="") But in this scenario i keep getting the first choice.

What am i missing

Oded
  • 489,969
  • 99
  • 883
  • 1,009
ntan
  • 2,195
  • 7
  • 35
  • 56
  • 9
    Why are you using a `switch` statement for a task that's best suited to an `if` statement? – Andy E May 04 '10 at 14:12
  • 1
    You're alerting "choice2" in both of the first two cases. Is that what you intended? – Syntactic May 04 '10 at 14:13
  • well you get a vote for an odd yet interesting question. so what are your possible values for `j.choice1` and `j.choice2`? – lincolnk May 04 '10 at 15:39

5 Answers5

38

It works for me:

var a = 0, b = true;
    
switch(true) {
    case a:
        console.log('a');
        break;
    case b:
        console.log('b');
        break;
}

However, the case labels must be equal to true, not just implicitly true.
Also, only the first case that evaluates to true will execute.

Pang
  • 9,564
  • 146
  • 81
  • 122
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 8
    If you are working with cases that don't explicitly evaluate to `true` (such as String.match()), you can use `!!` to quickly and legibly convert each case to a Boolean value. – superhawk610 Mar 13 '18 at 18:27
3

SOLVED

Based on SLaks answer i modify the code as below

    if(j.choice1){ var choice1=true;} else { var choice1=false;}
    if(j.choice2){ var choice2=true;} else { var choice2=false;}

    switch(true)
    {
        case choice1:
            alert("choice1");
        break;
        case choice2:
            alert("choice2");
        break;
        default:
            alert("default");
        break;
    }

For all asking why switch and not if.

Switch will execute only 1 statement, but if can execute more than 1 if any mistake come form response (for example if set choice1 and choice 2 the if will alert both but switch will alert only choice1).

The response expecting as choice has to do with credit card charge to bank so i want to ensure that only 1 action will exetute

Thank to all

ntan
  • 2,195
  • 7
  • 35
  • 56
  • 5
    An if/else if chain will execute at most one branch as well. – John Dvorak Nov 16 '12 at 13:12
  • You have that inverted. An `if statement` will only execute the single block, using `switch(true)` or `switch(false)` will allow you to fall through to a lower adjacent statement if you leave out the `break`. Beware the subsequent case you fall through to will not be evaluated. – Steve Buzonas Jan 02 '14 at 04:31
  • the two `if` block at the top is unnecessary, just do `!!j.choice1` or `Boolean(j.choice1)` or `j.choice1 == true` are good enough. – Valen Dec 16 '18 at 22:33
1

You need to read up on the switch statement. You should not be switching on a constant value.

It appears that you need to use if statements, as you don't really want to be switching on your j value:

success: function (j) {     
    if (j.choice1)
    {
        alert("choice1");
        break;
    }

    if (j.choice2)
    {
        alert("choice2");
        break;
    }

    alert("default");
  }
}
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 1
    Just curious: why should one not switch on a constant value? – Tim Down May 04 '10 at 14:43
  • It will provide the same result every time. It's somewhat akin to `if(x = y) condition` – Pops May 04 '10 at 15:01
  • @Lord Torgamus: technically, it would only be similar if `y` was always truthy or always falsey. – Matthew Crumley May 04 '10 at 16:26
  • @Matthew: I consciously decided not to go for that level of detail, but yes, you are correct. – Pops May 04 '10 at 18:42
  • @Lord Torgamus: I figured that. I just like to be pedantic sometimes, although, I guess "somewhat" kind of covers you there. – Matthew Crumley May 04 '10 at 19:06
  • 29
    I'm failing to see the real problem with using `switch` like this. The task is to find only the first occurrence of `true` in a short, pre-defined list of values, which the `switch` statement achieves correctly. The only other sane looking option that occurs to me is using `if/else if`. The `switch` statement to me is just as readable as `if/else if` and works just as well, so unless there's a performance issue (and I can't see why there would be), I don't see a problem. – Tim Down May 05 '10 at 08:50
  • 22
    @Tim Down - it is a very obscure usage and not apparent at first glance. I'd rather have my code be readable. – Oded May 05 '10 at 10:43
  • 3
    Oded: Fair enough, I agree it is uncommon and therefore requires more time to read and understand than it warrants. – Tim Down May 05 '10 at 10:57
  • 16
    Yes --- I think that you're being overly dogmatic about it, and I see a readability tradeoff either way. The `switch` statement gives me a visual cue that none of the following conditions will be evaluated, where with the series of `if`s I have to notice the `return`s to realize that. I think `switch(true)` is a good and useful idiom and shouldn't be rejected, though this _exact_ usage is not ideal. – JasonFruit Aug 10 '12 at 19:44
  • 15
    -1 stating that "You should not be switching on a constant value" without any further explanation is not very useful – Christophe Jul 18 '13 at 00:04
  • 1
    -1: In the sample code `switch(true)` may not be useful, but in a circumstance where you have a block of code to execute only if `c-b != a` and a block of code to execute for the above and `a+b = c` then you can omit the break from the first case `c-b != a` and both blocks will be executed for that case. – Steve Buzonas Jan 02 '14 at 04:38
  • As far as I'm aware, there's nothing wrong with `switch`ing on a constant value. For example: https://repl.it/NX1j/1 – tex Oct 28 '17 at 18:26
  • 2
    Also, I'd like to point out that, at this time, the MDN `switch` docs include an example that switches on `true`. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch – tex Oct 29 '17 at 22:15
  • 2
    @Tex - Just for the record, that example has been removed. – David Oct 08 '18 at 06:47
  • A great case for `switch (true)` is when you want to do different things for ranges: `switch(true) { case x < 0: log("<10"); break; case x < 10: "x>0 x< 10"}` almost [as nice as Ruby](https://www.rubyguides.com/2015/10/ruby-case/) `case capacity when 0 "You ran out of gas." when 1..20 "The tank is almost empty. Quickly, find a gas station!"` – Ruan Mendes Oct 21 '21 at 13:16
1

In a case like this, a better way to do this is probably something like:

success: function (j) {
    if(j.choice1 || j.choice2) {
        alert("choice2");
    } else {
        alert("default");
    }
}
Syntactic
  • 10,721
  • 3
  • 25
  • 25
0

Why not use an object literal instead of a switch(true) ?

const j= {
    choice1: false,
    choice2: true
};

const map = {
    true: 'default',
    ...(j.choice1 ? {[`${j.choice1}`]: 'choice1'} :{}),
    ...(j.choice2 ? {[`${j.choice2}`]: 'choice2'} :{})
}['true']

console.log(map) // 'choice2'
Tudor Morar
  • 3,720
  • 2
  • 27
  • 25