31

I have this code:

<div class="row list-group">
  <div *ngFor="let product of products" >
    <app-product [product]="product"></app-product>
  </div>
</div>

I was wondering is there any way i can get products from array in buckets? Something like this:

<div class="list-group">
  <div *ngFor="products; index+3" >
    <div class="row">
      <app-product [product]="products[index]"></app-product>
      <app-product [product]="products[index+1]"></app-product>
      <app-product [product]="products[index+2]"></app-product>
    </div>
  </div>
</div>

That way I could have all elements i need in a row

UPD

Thanks to Teddy Sterne I ended up with this solution:

<div class="list-group">
  <div *ngFor="let product of products;let i = index">
    <div class="row" *ngIf="i%3===0">
      <app-product [product]="products[i]"></app-product>
      <div *ngIf="products[i + 1]">
        <app-product [product]="products[i + 1]"></app-product>
      </div>
      <div *ngIf="products[i + 2]">
        <app-product [product]="products[i + 2]"></app-product>
      </div>
    </div>
  </div>
</div>
1
  • For anyone trying to display a variable number of objects in a grid, you may want to look into mat-grid: material.angular.io/components/grid-list/overview. (If the site doesn't load, try it in a new incognito window.) Commented Aug 16, 2018 at 16:24

3 Answers 3

52

Angular does not provide this functionality out of the box. I think that the simplest way to achieve the desired result is to only display data on every third index like so:

<div class="list-group">
  <div *ngFor="let p of products; let idx = index" >
    <div class="row" *ngIf="idx % 3 === 0">
      <app-product [product]="products[idx]"></app-product>
      <app-product [product]="products[idx+1]"></app-product>
      <app-product [product]="products[idx+2]"></app-product>
    </div>
  </div>
</div>

Demo

Sign up to request clarification or add additional context in comments.

3 Comments

Guess you need a bounds check for the index+1 and index+2 elements. Apart from that it should work :)
If the directive can handle undefined it should be okay. Otherwise yeah you could add an *ngIf to each row to prevent it.
@TeddySterne just a quick FYI, the DEMO link is not working.
4

For index try this:

Controller File add function :

chunks(array, size) {
  let results = [];
  while (array.length) {
    results.push(array.splice(0, size));
  }
  return results;
};

In you view file :

<div *ngFor="let chunkProduct of chunks(products,3);" >
  <div class="row">
      <app-product *ngFor="let product of chunkProduct" [product]="product"></app-product>
  </div>
</div>

This will work for all number , not only %3 numbers.

@Teddy Sterne's solution will work incase of the number is %3 If we have 8 products it will show only 6 last 2 will be lost , in this it will also be shown.

And it will create extra blank div tags for not %3 index , if you inspect the element and check , because it will loop through each product and div will get repeated no matter if its index %3 or not.

3 Comments

That will explode - aka give index out of bounds errors.
@VivekDoshi suppose products length is 6. What will happen to the last statement when index is 5?
It's broken. If the length is 2 it will try access index 1*3==3, which is clearly out of bounds.
1

Thanks Teddy Sterne for his answer.

Here's how it helped me to create a calendar control having 7 cells in a row

<div class="container-fluid">
  <table class="table table-bordered">
    <ng-container *ngFor="let d of data; let i = index" >
      <tr *ngIf="i % 7 === 0">
        <td *ngFor="let x of [i,i+1,i+2,i+3,i+4,i+5,i+6]">
          {{data[x]}}
        </td>
      </tr>
    </ng-container>
  </table>      
</div> 

DEMO

https://stackblitz.com/edit/angular-1nhor2?embed=1&file=src/app/app.component.html

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.