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>
Related
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 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>
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:-)
how to access the index of a ng-repeat?
I have the following code:
<ion-item ng-repeat="item in items track by $index" href="#/tab/friend/$index">
foo
</ion-item>
then I click a item from the list I get to: http://localhost:8100/#/tab/friend/$index
But I want to get to e.g. http://localhost:8100/#/tab/friend/12
what did I wrong?
Angular variables are only recognized automatically within ng- attributes. To use those variables within regular html attributes, you must use double braces:
<ion-item ng-repeat="item in items track by $index" href="#/tab/friend/{{$index}}">
foo
</ion-item>
You have placed $index in the string and there is no way for angular to know that it's an expression. To make angular evaluate it, you need to use it as an expression e.g. {{ $index }}. Modify your href as
href="#/tab/friend/{{$index}}"