angularjs: multiple values in a ng-switch-when
Asked Answered
C

7

61

I have the following ngSwitch:

<p ng-switch="status">
    <span ng-switch-when="wrong|incorrect">
       Wrong
    </span>
    <span ng-switch-default>
       Correct
    </span>
</p>

As you can see, I have the text Wrong for two options wrong and correct. I have tried (as you can see) to use the pipe |, but that doesn't work. Any suggestions ?

Cresset answered 24/3, 2014 at 13:16 Comment(2)
can you explain the logic of your switch statement, what are you trying to do?Sotos
I want to show the text wrong if the variable status contains the value wrong or incorrect. For all other values it should show the text CorrectCresset
S
76

For angular >=v1.5.10,

You can do it by adding ng-switch-when-separator="|" to ng-switch-when node. see example in documentation.

<span ng-switch-when="wrong|incorrect" ng-switch-when-separator="|">

see discussion here https://github.com/angular/angular.js/issues/3410 Note, based on my experience it doesn't work with numbers...yet?

Siskind answered 13/9, 2016 at 10:52 Comment(1)
Despite the documentation reading otherwise, this functionality isn't yet in v1.5.8, but will get into 1.5.9 onwards (see: github.com/flyfly6/angular.js/pull/1).Boob
C
43

This is almost same with using a ng-if, but the advantage of this is that you can use ng-switch-when="true" or default or false multiple times within main ng-switch.

<p ng-switch on="(status == 'wrong') || (status == 'incorrect')">
    <span ng-switch-when="true">
        Wrong
    </span>
    <span ng-switch-default>
       Correct
    </span>
</p>

Live : http://jsfiddle.net/8yf15t2d/

Clumsy answered 21/12, 2014 at 17:27 Comment(3)
Your answer should contain an explanation of your code and a description how it solves the problem.Wry
What is the advantage over "ng-if" ?Codicodices
If there are many switch cases then there is a performance benefit, as ng-if sets up a watcher for each ng-if, while ng-switch only sets up one watcher. This is most relevant if you're inside a ng-repeat, as then all these watchers would add up.Hobbledehoy
L
20

You can't have multiple conditions with a single ng-switch-when.

One alternative is to use an ng-if, but in the case of error handling, I prefer to populate an error variable on the scope in the controller, and use ng-show=error.

Libbi answered 24/3, 2014 at 13:25 Comment(0)
B
16

You can add a filter to the status that maps values that mean the same thing into the same value.

.filter('meaning', function() {
    return function(input) {
      input = input || '';
      if (['wrong', 'amiss','awry', 'bad', 'erroneous', 'false', 'inaccurate',\
           'misguided', 'mistaken', 'unsound', 'incorrect'].indexOf(input) != -1)
          return 'wrong';
      // You can make it generic like this:
      synonymsDictionary = {
        'someWord' : ['syn1', 'syn2', 'syn3' ... ],
        'someOtherWord' : ['otherWordSyn1', 'otherWordSyn2', 'otherWordSyn3' ...]
        .
        .
        .
      };

      for (var word in synonymsDictionary)
          if (synonymsDictionary[word].indexOf(input) != -1)
              return word; // This way you could iterate over a bunch of arrays...

         // Edge case
         else return input;
    };
  })

Then you simply

<p ng-switch="status|meaning">
    <span ng-switch-when="wrong">
       Wrong
    </span>
    <span ng-switch-default>
       Correct
    </span>
</p>

Although in your case, you may have just wanted to print a message so you could have pulled the message from a dictionary...

Something like:

<span ng-if="status">
    {{getStatusMessage(status)}}
</span>
Brosy answered 28/9, 2014 at 5:33 Comment(1)
very nice and under-ratedGutshall
M
5

This cannot be achieved with angular's base directives, but if you like, you could write your own directive to implement this, and could already interface with the existing ngSwitch directive.

ngSwitchController has one property cases which is a map. Every case key is prefixed with an ! and the default case is equal to ?. Each case value is an object with two properties: transclude and element.
Warning: Unlike ngModelController, ngSwitchController is not published API, so it's subject to change.

Based off of the original ngSwitchWhenDirective, we can construct a multiswitchWhen, that will work with all existing ngSwitch, ngSwitchWhen, and ngSwitchDefault directives without conflict.

.directive('multiswitchWhen', function () {
    return {
        transclude: 'element',
        priority: 800,
        require: '^ngSwitch',
        link: function(scope, element, attrs, ctrl, $transclude) {
            var selectTransclude = { transclude: $transclude, element: element };
            angular.forEach(attrs.multiswitchWhen.split('|'), function(switchWhen) {
                ctrl.cases['!' + switchWhen] = (ctrl.cases['!' + switchWhen] || []);
                ctrl.cases['!' + switchWhen].push(selectTransclude);
            });
        }
    }
});

Example plunker: http://plnkr.co/edit/K9znnnFiVnKAgGccSlrQ?p=preview

Matsu answered 3/8, 2015 at 17:27 Comment(1)
Excellent solution!. It Should be marked as the correct answer.Majordomo
S
3

You can add another switch case.

Example:

<p ng-switch="status">
    <span ng-switch-when="wrong">
       Wrong
    </span>
<span ng-switch-when="incorrect">
       Wrong
    </span>
    <span ng-switch-default>
       Correct
    </span>
</p>

Live example: http://jsfiddle.net/choroshin/Zt2qE/2/

Sotos answered 24/3, 2014 at 13:24 Comment(4)
This is correct, but it's not answering the question.Libbi
so what is the question?Sotos
multiple values in a ng-switch-when not just ng-switchLibbi
But why would you want multiple values in ng-switch-when? Why can't that be achieved using another ng-switch-when? I guess DRY reasons?Terena
N
0

ng-switch with option selection may help

<select ng-model="myVar">
  <option value="option1">Option 1
  <option value="option2">Option 2
  <option value="option3">Option 3
</select>
<div ng-switch="myVar">
  <div ng-switch-when="option1">
     <p>Option 1 is selected .</p>
  </div>
  <div ng-switch-when="option1">
     <p>Option 2 is selected</p>
  </div>
  <div ng-switch-default>
     <p>Option 3 is selected </p>
  </div>
</div>
Nudicaul answered 13/8, 2018 at 12:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.