Else if in angular js template [duplicate] - javascript

This question already has answers here:
if else statement in AngularJS templates
(10 answers)
Closed 8 years ago.
I need to use else if in angularjs template .What is the syntax ?
For example in c i would write the code like below:
if (data.sender=='system')
{data.receiver}
else if (data.sender=='mail')
{data.receiver}
else {data.sender}
My code:
{{data.sender == 'System' ? data.receiver : ' '}}
{{data.sender =='mail' ? data.receiver : data.sender }}

{{(data.sender === 'system' || data.sender === 'mail') ? data.receiver : data.sender}}

There are no if-else syntax in angular templates as you are looking for. Too much logic in the templates makes it difficult to maintain. Here are two possible solutions:
<span ng-show="data.sender == 'mail' || data.sender=='system'">{{data.receiver}}</span>
<span ng-show="data.sender != 'mail' && data.sender!='system'">{{data.sender}}</span>
You can also use ng-switch in a similar way:
<span ng-switch="data.sender">
<span ng-switch-when="mail">{{data.receiver}}</span>
<span ng-switch-when="system">{{data.receiver}}</span>
<span ng-switch-default>{{data.sender}}</span>
</span>
The later having the advantage that only one of the spans will exist in the document where ng-show/ng-hide all spans exist in the document they are just hidden using display:none.
Other options would be writing your own directive, or creating special filters.

Here it is, but you should really try to avoid having this kind of complicated logic inside of templates, as a rule of thumb.
{{ data.sender == 'system' ? data.receiver : data.sender == 'mail' ? data.receiver : data.sender }}

If you need an elseif in angular template you can use a ternary operator as in C/C++
{{ data.sender=='system'
< 4 ? data.receiver : data.sender=='mail' ? data.receiver : data.sender}}
angular.module('quetion_app', []);
angular.module('quetion_app').controller('quertion_controller', ['$scope',
function($scope) {
$scope.data = {
sender: 'some sender',
receiver: 'somebody'
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="quetion_app">
<div ng-controller="quertion_controller">
{{data}}
<br>
<br>
{{ data.sender=='system'
< 4 ? data.receiver : data.sender=='mail' ? data.receiver : data.sender}} </div>
</div>
Change data.sender in snippet to check the behavior
Hope it helps

This type of logic really belongs in the controller or service which is responsible for setting up data in your $scope. Placing it in your view brings a lot of logic in to the view unnecessarily and also causes that logic to be run as a watch which both expensive and unnecessary.
In the code that establishes data you could have:
data.displayedSender = (data.sender === 'system' || data.sender === 'mail') ? data.receiver : data.sender;
Then in your view you bind to the data.displayed sender:
<span>{{data.displayedSender}}</span>

Related

Angular translate filter in ternary operator

I'm trying to translate my project into another language. I used angular translate library and provided an external JSON file with the translations. It looks like this:
{
"hello_world": "Hola Mundo"
}
When I'm using it with simple hardcoded strings it works just fine and I get my correct translations:
<p>{{ "hello_world" | translate }}</p>
But how to deal with the ternary operator in code like this?
<button> {{ conditionValue ? 'Show' : 'Hide' }} </button>
How to change those 'Show' and 'Hide' values into a translation filter with Angular Translate? I tried different ways but I got an invalid syntax errors.
Thanks!
I think if you wrap the ternary operator into (), it will work.
<button> {{ ( conditionValue ? 'Show' : 'Hide' ) | translate }} </button>
you may try for this:
here i make username online and offline when you choose soanish, the user online status will change into spnish based on ternary condition.
https://plnkr.co/edit/o16dpI?p=preview
[https://plnkr.co/edit/o16dpI?p=preview][1]
{{ ( userName ? 'Show' : 'Hide' ) | translate }}
I've just come up with the solution!
For ternary operators we have to use 'translate' directive instead of filter. And it works just fine:
{
"show_value": "Show",
"hide_value": "Hide",
}
<button translate> {{ conditionValue ? "show_value" : "hide_value" }} </button>
If exist prefix
{{ ('massmedias.' + (ctrl.actionType === 'add' ? 'add' : 'rename')) | translate }}
Here is your language JSON file
"CONFIGURATION": {
"NEW_TEMPLATE": "New Template",
"EDIT_TEMPLATE": "Edit Template"
}
CASE-I (With HTML tag)
<button> {{ ( variable === '5' ? 'CONFIGURATION.NEW_TEMPLATE' : 'CONFIGURATION.EDIT_TEMPLATE' ) | translate }} </button>
CASE-II (With some third party attribute)
<p-dialog header="{{(variable === '5' ? 'CONFIGURATION.NEW_TEMPLATE' : 'CONFIGURATION.EDIT_TEMPLATE') | translate}}">

JXS if else class doesn't work

{item.status}
<div className="{item.status !== '' ? 'hide' : ''} pull-right">Content</div>
Why above jsx has no effect? My item.status value is string. But in my DOM I can't see hide class been added.
This is because you have wrapped your ternary operator in " so it is treated as string. Try this instead:
{item.status}
<div class={"pull-right "+(item.status !== '' ? 'hide' : '')}>Content</div>
Beside what #rahul-pratap-singh said, consider using nice, tiny package called classnames - link here so you can use it like:
import classes from 'classnames';
// later on
<div className={classes({
"pull-right": true,
"hide": item.status !== '',
})} />
I think it leads to much cleaner code than joining string.
Or at least use es6 string interpolation - link here
// instead of
"pull-right "+(item.status !== '' ? 'hide' : '')
// with string interpolation
`pull-right ${item.status.length ? '' : 'hide'}`;

Ng-class based on value returned from controller

I have tried to set icon style based on value returned from controller,the console log showing the value triggered correctly but it seems i have an issue with Ng-class expression. Any help on this is very much appreciated. Thanks in advance .
controller code
$scope.class = "favorite_border";
$scope.changeClass = function(){
if ($scope.class === "favorite_border")
$scope.class = "favorite";
else
$scope.class = "favorite_border";
console.log($scope.class);
}
view code
<i ion-ripple ion-ripple-color="#ff0000"class="material-icons" style="font-size: 32px" ng-click="changeClass()" ng-class="'{{class}}'== favorite_border ? 'favorite_border' : 'favorite'"> {{class}}</i>
CSS style
.favorite_border{ color:gray};.favorite{color:red};
Set your view like this:
<i ion-ripple ion-ripple-color="#ff0000"class="material-icons" style="font-size: 32px" ng-click="changeClass()" ng-class="class === 'favorite_border' ? 'favorite_border' : 'favorite'"> {{class}}</i>
or based on your controller code above:
<i ion-ripple ion-ripple-color="#ff0000"class="material-icons" style="font-size: 32px" ng-click="changeClass()" ng-class="class"> {{class}}</i>
Do not use expression while evaluation condition, change it as,
<i ion-ripple ion-ripple-color="#ff0000"class="material-icons" style="font-size: 32px" ng-click="changeClass()" ng-class="class === 'favorite_border' ? 'favorite_border' : 'favorite'"> {{class}}</i>
DEMO
.favorite_border{ color:yellow};.favorite{color:red};
<html>
<head>
<body>
<div ng-app="app" ng-controller="ctrl">
<i ion-ripple ion-ripple-color="#ff0000"class="material-icons" style="font-size: 32px" ng-click="changeClass()" ng-class="class == 'favorite_border' ? 'favorite_border' : 'favorite'"> {{class}}</i>
</div>
<!-- Angular Material Dependencies -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.js"></script>
<script>
var app = angular.module('app', []);
app.controller("ctrl", function($scope) {
$scope.class = "favorite_border";
$scope.changeClass = function(){
if ($scope.class === "favorite_border")
$scope.class = "favorite";
else
$scope.class = "favorite_border";
console.log($scope.class);
}
});
</script>
</body>
</html>
Just change it to
ng-class="class == 'favorite_border' ? 'favorite_border' : 'favorite'"
or even
ng-class="class"
Just remember to initialize $scope.class='...' with the appropriate initial class you want.
Exaplanation:
The expression in the ng-class will be evaluated as more or less expression in JS - with variables being prefixed with $scope. Therefore, if we look at your expression:
'{{class}}'== favorite_border ? 'favorite_border' : 'favorite'
it will be interpreted as:
'{{$scope.class}}'== $scope.favorite_border ? 'favorite_border' : 'favorite'
which in turn will be inferred as:
''== $scope.favorite_border ? 'favorite_border' : 'favorite'
initially, until you toggle the class, and
'favorite_border'== $scope.favorite_border ? 'favorite_border' : 'favorite'
None of them make sense in the context (first and second will be false ? 'favorite_border' : 'favorite' ==> 'favorite') and will not evaluate to an intended class name.

ng-class not working. Where did I do wrong?

I know there are many problems here listed like this. but I can't pinpoint where I did wrong..
<li ng-repeat="item in type.sub | orderBy:y" ng-click="openpic($parent.$index, $index)" ng-class="{ 'active': $parent.$index + ':' + $index == current }">
we have $scope.current variable, and a nested menu with numbering id like 1:2, 1:3, 1:4, 2:1, 2:2, 2:3 and so on.
Goal is very simple. I need to make this <li> active, if the $parent.$index:$index is equal to $scope.current. ID is set whenever openpic($parent.$index, $index) triggered. We have li.active class in css.
So, can someone please show me, what's missing in that code?
TRY 1:
Tried:
<li ng-repeat="item in type.sub | orderBy:y" ng-click="openpic($parent.$index, $index)" ng-class="{ 'active': $parent.$index + ':' + $index == $parent.current }">
Still not working.
TRY 2
I have something like this:
ng-class="{{ $parent.$index + ':' + $index == $parent.current && 'active' || '' }}"
and it shows as ng-class="active" but class attribute did not updated.
TRY 3
ng-class="{{ $parent.$index + ':' + $index == $parent.current && 'highlight' || '' }}"
it shows ng-class='highlight", but class still shows class="ng-binding ng-scope"
TRY 4
ng-class="isActive($parent.$index,$index)"
It solves the problem, but it seems a little bit overkill for a simple switch function. Any more ideas?
TRY 5
As per major-mann code suggestion that works at TRY 4, I made these adjustment, and surprisingly, it works.
ng-class="$parent.$index + ':' + $index == $parent.current && 'active' || ''"
That one works. Removed all braces completely ????
First of all make {{$parent.$index:$index}} to make sure to get the right data (I just never met such a method to data access) ;
If it's ok, then try use:
ng-class="$parent.$index:$index === current ? 'active' : ''"
Or (best way) use function for this:
ng-class="someFn($parent.$index)"
$scope.someFn = function(index){
//index, index:index, index[n] or something else;
return index === $scope.current ? 'active' : '';
};
Update:
If You want get access to parent ng-repeat, better use
<... ng-repeat="(index1, data1) in firstData">
<... ng-repeat="(index2, data2) in secondData">
<... ng-something="index1 operator index2 or function(index1, index2)">
I hope, it will help;
As pointed to in the comments, rather a non-answer, but usually it is best practice to try to keep code (even simple ternaries) inside the JavaScript blocks rather than inside the HTML. This generally makes debugging any issues you may be having infinitely easier to deal with.
So, for example, you could change your HTML to something like:
<li ng-repeat="..." ng-click="..." ng-class="isActive($parent.$index, $index)">
And in your controller, you could add something like:
$scope.menu= function isActive(pidx, idx) {
return {
active: pidx + ':' + idx === $scope.current
};
};
To achieve your desired result.
If you take this a step further, you will probably realize that it is even better to do something like
$scope.cls.menu = function(pidx, idx) {
return {
active: pidx + ':' + idx === $scope.current,
any: 'other',
dynamic: 'classes',
you: 'need'
};
}
And call the function appropriately in the view.

AngularJS - HTML data binding UI issue

I am binding following in my HTML.
<div>{{user.address[0].addressline1}}, {{user.address[0].addressline2}}, {{user.address[0].city}}, {{user.address[0].state}}, {{user.address[0].zipcode}}</div>
The issue is if addressline1 is null, it unnecessarily shows the , at first.
And also some other fields can be null
So How to display comma only if the value is not null?
Or as a matter of style, you can use a turnery operator to check for the value then format it
{{ !!user.address[0].addressline1 ? user.address[0].addressline1 + ', ' : ''}}
This could be made as filter to be more intuitive
angular.module('myapp', []).filter('trailIfTrue', [function(){
return function(val, trail){
return !!val ? val + trail : '';
}
}]);
usage:
{{ user.address[0].addressline1 | trailIfTrue:',' }}
here is a plunker
User separate span and ng-show so the span will be shown only if user.address[0].addressline1 is not null
<span ng-show="user.address[0].addressline1">{{user.address[0].addressline1}},</span>
<span ng-show="user.address[0].addressline2">{{user.address[0]. addressline2}},</span>
<span ng-show="user.address[0].city">{{user.address[0].city}},</span>
//...
You can use any expression into ng-show Eg:
user.address[0].addressline1 != null
myObj.myIntAttr > 0 && < 10
myObj.myBoolAttr == false
//...

Categories

Resources