Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping through list two at a time using *ngFor

Tags:

angular

I have a list of jobs that I want to display within <ion-row>. Each row can contain a maximum of two jobs. Each job is wrapped within a <ion-col> tag.

<ion-row>
    <ion-col width-50 class="job-item">Job A</ion-col>
    <ion-col width-50 class="job-item">Job B</ion-col>                              
</ion-row>  

I need to be able to loop through the jobs:

<ion-row>
    <ion-col *ngFor="let job of jobs" width-50 class="job-item">{{ job.name }}</ion-col>                            
</ion-row>  

But the problem with this is that all the jobs show within the same <ion-row> tag.

Instead I need something like this pseudo code:

<ion-row>
    <ion-col>1</ion-col>
    <ion-col>2</ion-col>
</ion-row>  
<ion-row>
    <ion-col>3</ion-col>
    <ion-col>4</ion-col>
</ion-row>  
<ion-row>
    <ion-col>5</ion-col>
    <ion-col>6</ion-col>
</ion-row>  
<ion-row>
    <ion-col>7</ion-col>
</ion-row>      

How can I achieve this? Presumably making use of odd/even numbers?

like image 811
Chris Avatar asked Apr 05 '17 14:04

Chris


3 Answers

create a pipe that does the split:

@Pipe({ name: "row" })
export class RowPipe implements PipeTransform {
  // input is an array of any
  // mod is the modulo, every mod items, create a row
  transform(input: any[], mod: number): any[][] {
    return input.reduce((previous, next, index) => {
      if (index % mod === 0)
        previous.push([next]);
      else
        previous[previous.length - 1].push(next);
      return previous;
    }, <any[][]>[]);
  }
}

then :

<ion-row *ngFor="row of jobs|row:2">
    <ion-col *ngFor="let job of row" width-50 class="job-item">{{ job.name }}</ion-col>                            
</ion-row>  
like image 110
n00dl3 Avatar answered Sep 30 '22 12:09

n00dl3


The best way to do this is by transforming the structure of your jobs array so that it is an array of arrays. Then the structure you want is easy:

<ion-row *ngFor='let row of jobRows'>
    <ion-col *ngFor="let job of row">{{ job.name }}</ion-col>                            
</ion-row>

Where you do the transformation is mostly dependent on your app, but you could do it in a pipe:

@Pipe({
    name: 'toRows'
})
export class ToRowsPipe implements PipeTransform {

    transform<T>(value: T[], perRow: number): T[][] {
        let rows: T[][] = [];
        for (let i = 0; i < value.length; i += perRow) {
            rows.push(value.slice(i, i + perRow))
        }
        return rows;
    }

}



<ion-row *ngFor='let row of jobs | toRows:2'>
    <ion-col *ngFor="let job of row">{{ job.name }}</ion-col>                            
</ion-row>
like image 39
adharris Avatar answered Sep 30 '22 10:09

adharris


The simplest solution is to apply *ngFor on and give the size attribute as necessary. In your case, it would be 6 since the total is 12. So that creates rows of 2 columns each.

<ion-row>
 <ion-col *ngFor="let job of jobs" size="6">
  {{ job.name }}
 </ion-col>                            
</ion-row> 
like image 39
Shabir Hamid Avatar answered Sep 30 '22 10:09

Shabir Hamid