Hi,
I've recently found out that ng-switch-when expects a primitive value as an attribute, I always thought it was an expression. So I've made a fix that allows to use expressions as well.
I'm using it because I need to use constants in my code instead of magic values.
Ex:
<div ng-switch on="myScope.type">
<span ng-switch-when-expr="myScope.types.TYPE1">Type 1</span>
<span ng-switch-when-expr="myScope.types.TYPE2">Type 2</span>
<span ng-switch-when-expr="'STRING'">String</span>
<span ng-switch-default>undefined</span>
</div>
Tell me what do you think before I make a PR
I'm pretty sure that there are issues / PRs for this already
This has been requested in #5409 (possibly among others) and seems like it is a _won't happen_ :)
(for the reasons explained there).
Basically, this is slightly different as it proposes a new attribute (ng-switch-when-expr), rather than enhancing the existing ng-switch-when.
I still believe don't see much benefit in it. If you want to watch multiple expressions, why not use ngIfs instead ?
OK, closing as duplicate of #5409. If people still think that it should be part of the core, the lobbing should be done in #5409 :-)
Lobbying in closed issues is probably not the best idea. We also discussed using the supercharged ngMessages @matsko is working on as the new ngSwitch, which would have support for expressions, so this is not as far-fetched.
I am not so sure it will have support for expressions (nor do I get the point :))...
I already knew it was not accepted on ng-switch-when, hence the new directive. I just don't know why the bother, why is it defeating the purpose exactly? Essentially, I can understand why this could be weird to match against a scope entry, but consider the following code, perfectly valid in Javascript:
function fizzbuzz(x, y, z) {
switch (x) {
case y: return 'fizz';
case z: return 'buzz';
default: return x;
}
}
var number = 3;
fizzbuzz(number, 3, 5);
// -> returns 'fizz'
number = 10;
fizzbuzz(number, 3, 10);
// -> returns 'buzz';
Yes I do understand this is not elegant, as it would be better expressed with if expressions, but this is nonetheless valid. So why not in angular?
As to why I need this, like I said: for "enums" (see my example before). The only way right now would be either to use magic values (and thus if I change the string, I need to find out EVERY PLACE it would be defined); or using ng-if, leading to many if branches. And in that case, why ng-if would be better than ng-switch ?
@gkalpak You don't see the reason for using expressions or for the new ngMessages?
How would I use it with ng-messages?
You wouldn't at the moment. There was a (currently internal) proposal for extending ngMessages with new features which could also benefit ngSwitch.
@mallowigi once #10676 goes through:
<div ng-messages="ngModel.$error">
<div ng-message-match="exp">{{ expMessage }}</div>
<div ng-message-match="['minlength', 'maxlength']">Your value must be between 10 and 20 characters</div>
<div ng-repeat="error in errors">
<div ng-message-match="error.name">{{ error.message }}</div>
</div>
</div>
@mallowigi perhaps maybe we could have a combined directive in the future.
@gkalpak You don't see the reason for using expressions or for the new ngMessages?
@Narretz: For expressions of course :) The newngMessagesis pretty cool.
I understand the need for dynamicly set keys, but I believe we could get away with a one-of evaluation.
Not sure there is much benefit in constantly watching the expressions (especially considering that one simple form can easily end up with dozens of ngMessages).
Exactly, with bindonce, no need to assign watchers for the when expressions, and we still benefit from using constants.
I still believe don't see much benefit in it. If you want to watch multiple expressions, why not use ngIfs instead ?
@gkalpak A valid use case in my opinion is not when you want to watch multiple expressions, but when you have for example an error object with string error codes in it, and you want to display a message depending on what the error code is. ng-switch seems ideal for this purpose, but it doesn't work as you need to supply static values...
Basically, what I'd want is support for the following:
<p ng-switch="error.code">
<p ng-switch-when="{{errors.someErrorCode1}}"></p>
<p ng-switch-when="{{errors.someErrorCode2}}"></p>
...
<p ng-switch-default></p>
</p>
I don't think ng-messages has support for a default.
Even in Angular2 they supported it...
Oh well, I'll be upgrading to ng2 soon enough >.<
For reference, I've just tackled this with some extra redundant code in the directive controller:
//Find error code in errors dictionary
for (var key in errors) {
if (error.code === errors[key]) {
$scope.error = key;
break;
}
}
This just sets the string key name of the error in the scope, and then you can use literals in your template:
<p ng-switch="error">
<p ng-switch-when="someErrorCode1"></p>
<p ng-switch-when="someErrorCode2"></p>
...
<p ng-switch-default></p>
</p>
Ugly workaround, but at least you get a clean template without === expressions and you get a properly working default option.
Has this been fixed or is it being closed because it's not going to happen?
I don't know why the OP closed it. This is not something that was on
schedule or anything but since the same is possible in Angular we'd
definitely consider a well implemented PR
This issue has been opened more than two years ago. At this point it doesn't matter whether this feature will be implemented or not.
@mallowigi What do you mean? Yes, maybe it doesn't matter for you, and clearly, since there hasn't been much interest in it, it's not something that's very important, but that doesn't mean it couldn't help people in the future.
Most helpful comment
@mallowigi What do you mean? Yes, maybe it doesn't matter for you, and clearly, since there hasn't been much interest in it, it's not something that's very important, but that doesn't mean it couldn't help people in the future.