I am attempting to filter a list of items the code below worded fine in angular js on the web but we can't expect Ionic to work now can we?
<ion-list *ngIf="items.length">
{{items[0].title}}
<ion-item ng-repeat="item in items | filter:searchLog">
{{item == undefined}}
<!--<ion-icon name="clipboard" item-left></ion-icon>
<h2><b>Title: {{item.title}}</b></h2>
<h3><b>Caller: {{item.caller.name}} - {{item.caller.number}}</b></h3>
<h3><b>Location: {{item.caller.location}}</b></h3>
<h3><i>Dispatcher: </i>{{item.dispatcher.name}} at {{item.timeStamp}}</h3>
<h3><b>Dropped: {{item.canceled}}</b></h3>
<h3 style="white-space: normal;"><i>Details:</i> {{item.details}}</h3>-->
</ion-item>
</ion-list>
This is what my screen shows:
car out of gas
true
For the life of me I cannot understand this because if I print {{ items[0].title }} it works fine in the repeat list meaning that it is not giving me this item object back from the ng-repeat call. What is even weirder is that *ngFor works but I cannot filter it :-( Please help
TL;DR: ng-repeat in angular is returning one undefined object.
Use *ngFor with pipe (i.e. filter). If it is still not working then there is some problem with your pipe (filter). Code should look like below:
<ion-list *ngIf="items.length">
{{items[0].title}}
<ion-item *ngFor="let item of items | searchLog">
<ion-icon name="clipboard" item-left></ion-icon>
<h2><b>Title: {{item.title}}</b></h2>
<h3><b>Caller: {{item.caller.name}} - {{item.caller.number}}</b></h3>
<h3><b>Location: {{item.caller.location}}</b></h3>
<h3><i>Dispatcher: </i>{{item.dispatcher.name}} at {{item.timeStamp}}</h3>
<h3><b>Dropped: {{item.canceled}}</b></h3>
<h3 style="white-space: normal;"><i>Details:</i> {{item.details}}</h3>
</ion-item>
</ion-list>
Related
I have 2 nested ngFor loops.
The first
<ion-item-group *ngFor="let team of shift.teams_assigned">
Defines team and I would like to use team as a selector for a child loop like this
<ion-item *ngFor="let member of shift.members_assigned.team">
Is there a specific syntax to access the key of an array like members_assigned.$_variable_key_i_want_to_loop
You should do it like that if I well understand your question because it is not clear to me
<ion-item *ngFor="let team of shift.teams_assigned">
<ion-item *ngFor="let member of team">
</ion-item>
</ion-item>
I have this html code
<empty-list [hidden]="!emptylist" text="There is currently No User"</empty-list>
<div *ngFor="let userObser of userObservables">
<ion-item #emptylist *ngIf="userObser | async as user">
<h2>{{user.displayName}}</h2>
<h3>{{user.email}}</h3>
</ion-item>
</div>
I want to show the empty list if there is no user & hide it if there is at least one.
I know I can do it using a subscribe method,but I want to use async pipe also I need to unsubscribe each time I use a subscribe which is really not efficient.
My question is there a way I could create a local variable inside the ion-item the ntest test if it exists outside & therefore use it in the hidden input ? It's just a suggestion I can't really seem to make it work.
You can use a simple else inside the ngIf to display another template if the condition doesn't match:
<ng-container *ngIf="userObservables.length > 0; else emptyList">
<ng-container *ngFor="let user of userObservables">
<ion-item *ngIf="user | async as user">…</ion-item>
</ng-container>
</ng-container>
<ng-template #emptyList>
<empty-list>…</empty-list>
</ng-template>
Note that I also replaced your seemingly unnecessary div with a ng-container to avoid unnecessary DOM nodes.
As a side note to your own suggestion: template references cannot be accessed from outside the template boundary. Structural directives like *ngIf and *ngFor create their own template, so this becomes a boundary. That's why
<h2>{{ ref.innerText }}</h2>
<ng-container>
<span #ref>Hello, World</span>
</ng-container>
will work, but
<h2>{{ ref.innerText }}</h2>
<ng-container *ngIf="true">
<span #ref>Hello, World</span>
</ng-container>
won't work.
When iterating through an array of items for ngFor, the (click) event is failing to attach to each list item, for some reason it just doesn't attach and when I click on each of the list items, the function is not triggered.
Here is the HTML for the list:
<ion-list class="queue-page--actions__haircut__tab-open" radio-group *ngIf="haircutTab" [(ngModel)]="selectedCut">
<ion-list-header class="queue-page--actions__haircut__tab__header">
Select a cut
</ion-list-header>
<ion-item *ngFor="let item of getCuts()" (click)="open($event, item)">
<ion-label>{{item.name}}</ion-label>
<ion-label>£{{item.price}}</ion-label>
<ion-radio checked="{{item.name == selectedCut}}" value="{{item.name}}"></ion-radio>
</ion-item>
</ion-list>
Get cuts is the function on the controller for the page (this.cuts is of type array and returns an array of json objects):
public getCuts(){
return this.cuts;
}
And finally, the open() function is as follows:
public open(event, item){
alert("Clicked");
console.log(item)
}
Can't figure out what's going wrong here, perhaps a suspicion of scope issues but really not sure.
Try like this
<ion-item *ngFor="let item of cuts" (click)="open(item)">
:
</ion-item>
Thanks to this post on the Ionic 2 forum I have found a solution to the problem presented here.
Instead of using (click), I am now using (ionSelect) on the ion-radio element. An example can be seen here:
<ion-item *ngFor="let item of cuts" (click)="open(item)">
<ion-label>{{item.name}}</ion-label>
<ion-label>£{{item.price}}</ion-label>
<ion-radio (ionSelect)="cutChanged(item.name)" checked="{{item.name == selectedCut}}" value="{{item.name}}"></ion-radio>
</ion-item>
Where the function on the controller for cutChanged() is like so:
cutChanged(cut){
alert(cut);
}
This implementation now works and fires on click events. Perhaps something unusual with how radio buttons work in Ionic?
Your getCuts() method is not required.
No need to pass the event when the open() function is called. Also there is a semicolon missing in your open() method. Final Code :
<ion-list class="queue-page--actions__haircut__tab-open" radio-group *ngIf="haircutTab" [(ngModel)]="selectedCut">
<ion-list-header class="queue-page--actions__haircut__tab__header">
Select a cut
</ion-list-header>
<ion-item *ngFor="let item of cuts" (click)="open(item)">
<ion-label>{{item.name}}</ion-label>
<ion-label>£{{item.price}}</ion-label>
<ion-radio checked="{{item.name == selectedCut}}" value="{{item.name}}"></ion-radio>
</ion-item>
</ion-list>
open() function will be :
public open(event, item){
alert("Clicked");
console.log(item);
}
I am trying to use ngIf within an ngFor but it's just breaking my code. Below is my code:
<ion-row *ngIf="{{i % 3}}===0" *ngFor="let category of categories; let i=index">
I need to check if the index mod 3 is equal to zero
You can overwrite your code like:
<ion-row *ngFor="let category of categories; let i=index">
<ng-container *ngIf="{{i % 3}}===0">
...
</ng-container>
</ion-row>
ng-container behaves the same as template but you can use common syntax like *ngIf and *ngFor
you can't put ngIf on the same component as ngFor
Angular disallows such construction
Using i before initializing it in ngFor will never work
If you *ngIf gets a false value the *ngFor would never be created in the first place - see point 1:-)
I Am trying to fetch data from http, json array and display in list view and there is over 1000 items and loading all of them at once makes scrolling so laggy and am trying to load 20 items first and when scrolled down i want to load more 20 items but my code is not working. Can anyone help me out.
HTML
<ion-content ng-controller="ListController" on-infinite-scroll="addMoreItem" class="has-subheader" scroll-watch >
<ion-list >
<ion-item href="{{ item.url }}.jpg" ng-repeat="item in id | limitTo:numberOfItemsToDisplay" class="item-thumbnail-left item-text-wrap" >
<img src="{{ item.thumbnailUrl }}.jpg" alt="Photo">
<h2>
{{item.id}}
</h2>
<p>{{item.title}}</p>
</ion-item>
</ion-list>
</ion-content>
AngularJS
.controller('ListController',['$scope','$http',function($scope,$http){
$http.get('http://jsonplaceholder.typicode.com/photos').success(function(data){
$scope.id = data;
})
$scope.numberOfItemsToDisplay = 20; // number of item to load each time
$scope.addMoreItem = function(done) {
if ($scope.item.length >= $scope.numberOfItemsToDisplay)
$scope.numberOfItemsToDisplay += 20; // load 20 more items
done(); // need to call this when finish loading more data
}
}])
When dealing with huge lists, ionic suggest that you should use the collection-repeat directive instead of ng-repeat cause it gives a far more better performance. collection-repeat renders into the DOM only as many items as are currently visible and thats how it keeps the performance up. Please read more on the official doc here: collection-repeat
I suggest solving it through infinite-scroll.. :)