AngularJS : IF Statement inside "ng-repeat"? - angularjs

I'm using AngularJS v1.2.9.
Inside ng-repeat, how do i use check the value of object and do action based on condition?
In English, something like:
if `X` is not null, then show `X`. Is it possible?
Here's my ng-repeat skeleton:
<li ng-repeat="r in results">
<div>{{ r.title }}</div>
<div>{{ r.location }}</div>
<!--
if ( r.date!=="null" ) {
<div>{{ r.date }}</div>
} else {
<div>Date not confirmed yet.</div>
}
-->
</li>
I need to show r.date if it is not null. If it is null, then i say something else.
Please kindly help. Thanks all.

<li ng-repeat="r in results">
<!-- If r.date contains a value, show it -->
<span ng-if="r.date">{{r.date}}</span>
<!-- If r.date does not contain a value show placeholder text -->
<span ng-if="!r.date">Date not confirmed yet.<span>
</li>
Also see What does an exclamation mark before a variable mean in JavaScript

Update
Question wasn't much clear so here is what you wanted just by having ng-bind directive in place. If the content is bigger then you can switch to the way suggested by #JustOneMoreQuestion below.
<li ng-repeat="r in results" ng-if="r.date">
<div ng-bind="r.date ? r.date : 'Date not confirmed yet.'"></div>
</li>
You could easily do by using ng-if
<li ng-repeat="r in results" ng-if="r.date">
<!--
if ( r.date!=="null" ) {
{{ r.date }}
}
-->
</li>
OR go for a filter which will filter out those will create a collection of element which has date in it.
<li ng-repeat="r in results| filter: { date: '' }">
<!--
if ( r.date!=="null" ) {
{{ r.date }}
}
-->
</li>

Check this one,
<li ng-repeat="r in results" >
<div data-ng-if="r.date !== 'null'">
Your Date
</div>
<div data-ng-if="r.date == 'null'">
Date not confirmed yet
</div>
</li>

Related

Why nothing is displayed in list initially when i use ! (not) in AngularJS filter?

<p><input type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter:'!'+test">
{{ x }}
</li>
</ul>
How to display all the items in list initially and then exclude the items as i type? Initially, none of the items are displayed. Only after i type something in textbox, it displays the items excluding the one which i typed.
You are missing angularjs strict:true operator in filters
this is what you need
<li ng-repeat="x in names | filter:'!'+test:true">
{{ x }}
</li>
Plnkr
On top of my head setting an initial value in model $scope.test = '' should resolve the issue for you.
No need of this '!' ,you just have to pass ng-model value
<p><input type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter:test">
{{ x }}
</li>
</ul>

Avoid multiple use of a Filter in AngularJs

I am trying to avoid using the same filter on the same collection multiple times in AngularJS application.
What is the correct way to do it:
<div ng-app="myApp" ng-controller="PeopleCtrl">
<ul ng-init="(person in people|filter:{show:true}) as myPeople" ng-if="myPeople.length>0">
<h4>My People</h4>
<li ng-repeat="person in myPeople">{{person.name}}; display: {{person.show}};
</ul>
</div>
CODE PEN
When I use (person in people|filter:{show:true}) as myPeople I try to use an alias in order to not repeat the same filter{show:true} everywhere...
You should do it something like this:
<div ng-init="myPeople = (people | filter:{show:true})">
<div ng-if="myPeople.length>0">
<h4> My People</h4>
<ul>
<li ng-repeat="person in myPeople">
{{person.name}}; age: {{person.age}}; show: {{person.show}};
</li>
</ul>
</div>
</div>

Angular switch from ng-show to ng-repeat filter / how to

What is the correct syntax to switch from my simple ng-show to a filter in my ng-repeat? (item in list | filter:{item.value == 'abc'} or so)
<ol ng-repeat="item in list">
<li ng-show="item.value == 'abc'">test</li>
</ol>
Do not use ng-repeat inside <ol> tag.
This will repeat <ol> tag each time with single <li>.
Use ng-repeat in <li> tag to repeat <li> tag inside <ol> tag and use filter with ng-repeat.
use like this :
<ol>
<li ng-repeat="item in list | filter: { value : 'abc' }">test</li>
</ol>
working plunkr
<ol ng-repeat="item in list | filter:{value: 'abc'}">
<li>test</li>
</ol>
Plunker: https://plnkr.co/edit/uw0LNygWbj4Njhp1n7PN?p=preview
Try this
<ol ng-repeat="item in list | filter: {value: 'abc'}">
<li>test</li>
</ol>
Angular Filter doc
You can use nf-repeat Filter
<ol ng-repeat="item in list | filter : {value : 'abc'}">
<li>test</li>
</ol>
read AngularJS API Document

Is there a "with... as..." clause in angular?

Here is my use case
<li ng-repeat="item in heterogeneousFruitArray">
<div ng-if="item.type == 'apple'">
... custom apple stuff ...
</div>
<div ng-if="item.type == 'orange'">
... custom orange stuff ...
</div>
... stuff for all fruits ...
</li>
It would increase readability if I could say
<li ng-repeat="item in heterogeneousFruitArray">
<div ng-if="item.type == 'apple'">
<span ng-with="item as apple">
<h1>{{apple.name}}</h1>
Crispness: {{apple.crispness}}
... and so on...
</span>
</div>
...
</li>
Is there a way to do this with angular?
I realize that this pattern could be me coding with an accent because of my django templates background. If I'm miles away from 'how it's done in angular', please let me know.
ngInit was designed with aliasing in mind, especially within an ngRepeat:
<li ng-repeat="item in heterogeneousFruitArray">
<div ng-if="item.type == 'apple'" ng-init="apple=item">
... custom apple stuff ...
</div>
<div ng-if="item.type == 'orange'" ng-init="orange=item"">
... custom orange stuff ...
</div>
... stuff for all fruits ...
</li>
Here is official documentation on ngInit:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
Demo Plunker
In tandem with ngInit for aliasing, you should also consider using ngSwitch, instead of having multiple ngIfs where only one is evaluated to true at a time.
Using ngSwitch has the same result, but increases readability and is more efficient as it evaluates the condition once in every digest loop (in contrast to multiple ngIfs where the same expression is evaluated once for every ngIf).
E.g.:
<li ng-repeat="item in heterogeneousFruitArray">
<div ng-switch="item.type">
<!-- Apple-specific template -->
<span ng-switch-when="apple" ng-init="apple=item">
<h1>{{apple.name}}</h1>
Crispness: {{apple.crispness}}
</span>
<!-- Orange-specific template -->
<span ng-switch-when="orange" ng-init="orange=item">
<h1>{{orange.name}}</h1>
Juicy-ness: {{orange.juicyness}}
</span>
<!-- Default template (used when `item.type` is unknown/unexpected) -->
<span ng-switch-default ng-init="unknown=item">
<h3>What kind of fruit is "{{unknown.type}}" ???</h3>
</span>
</div>
</li>
You can always use AngularJS Filters to implement that.
Html:
<div ng-app='myApp' ng-controller='myCtrl'>
<ul>
<li ng-repeat='item in items | filter:{name: "orange"}'>
{{item.id}} - {{item.name}}
</li>
</ul>
</div>
Js:
var app = angular.module('myApp',[]);
app.controller('myCtrl', function($scope){
$scope.items = [
{
id: 12,
name: 'apple'
},
{
id: 13,
name: 'orange'
},
{
id:14,
name:'grape'
}
];
});
JSFiddle.

Two ng-repeat, one affect another

Today I faced a strange problem for me in AngularJS.
In this example I have two ng-repeat in product (two or three images and the same number of colors) and one ng-repeat for pagination (irrelevant in this case I assume).
HTML:
<div class="item-wrapper" ng-repeat="item in pagedItems[currentPage]">
<div class="item">
<!-- Item image -->
<div class="item-image">
<ul>
<li ng-repeat="desc in item._source.description" ng-show="$first">
<img class="preview" ng-src="server/{{desc.smallImage.url}}">
</li>
</ul>
</div>
<!-- Item details -->
<div class="item-details">
<div class="product-colors">
<ul class="btn-group pull-right">
<li ng-repeat="color in item._source.description">
<img class="color" ng-src="server/{{color.thumbnailImage.url}}" />
</li>
</ul>
</div>
</div>
</div>
All I wanted to do is that click on one of colors (img.color) changes corresponding img.preview visibility. In my attempts I was always able to changed every img.preview in whole list, not the one I clicked on.
MY ATTEMPTS:
HTML
<li ng-repeat="desc in item._source.description" ng-show="$index === selectedColor">
<li ng-repeat="color in item._source.description" ng-click="changeColor($index)">
JS (controller)
$scope.changeColor = function(idx) {
$scope.selectedColor = idx || 0; //default show always first img.preview from list
};
MY ATTEMPTS #2 (working)
HTML
<li><img class="preview" ng-src="server/{{desc[__selected === $index ? __num : 0].smallImage.url}}">
<li ng-repeat="color in item._source.description" ng-click="changeColor($index, key)">
JS (controller)
$scope.changeColor = function(idx, key) {
$scope.__selected = key;
$scope.__num = idx;
};
This might be quite simple:
Considering desc and color will be referring to same object as they are of the same source.
So, desc and color should be identical and setting a property on either of them supposed to reflect on the other.
Make the changes as follow and try, havent tested though:
<li ng-repeat="desc in item._source.description" ng-show="item.__selected ? desc==item.__selected : $first">
and
<li ng-repeat="color in item._source.description">
<img class="color" ng-src="server/{{color.thumbnailImage.url}}" ng-click="item.__selected = color" />
</li>

Resources