How to add Row after every 3 columns in angular

What i am trying to do is add a row div after every 3 colum divs

Example Output need:

<div class="row">
     <div class="col-md-6"></div>
     <div class="col-md-6"></div>
     <div class="col-md-6"></div>
</div>

I have an array of products i am iltrating like this

<div class="row" *ngFor="let p of relatedProperties;let i = index">
    <div class="col-md-6"  *ngIf="relatedProperties[i].title !== undefined">{{ relatedProperties[i].title }}</div>
    <div class="col-md-6" *ngIf="relatedProperties[i].title !== undefined">{{ relatedProperties[i].title }}</div>
    <div class="col-md-6" *ngIf="relatedProperties[i].title !== undefined">{{ relatedProperties[i].title }}</div>
  </div>

But the problem is that my every row prints same title on one iltration and second on next iltration

Current output

<div class="row">
     <div class="col-md-6">Title1</div>
     <div class="col-md-6">Title1</div>
     <div class="col-md-6">Title1</div>
</div>

<div class="row">
         <div class="col-md-6">Title2</div>
         <div class="col-md-6">Title2</div>
         <div class="col-md-6">Title2</div>
</div>

<div class="row">
             <div class="col-md-6">Title3</div>
             <div class="col-md-6">Title3</div>
             <div class="col-md-6">Title3</div>
</div>

Desired Output

<div class="row">
         <div class="col-md-6">Title1</div>
         <div class="col-md-6">Title2</div>
         <div class="col-md-6">Title3</div>
    </div>

    <div class="row">
             <div class="col-md-6">Title4</div>
             <div class="col-md-6">Title5</div>
             <div class="col-md-6">Title6</div>
    </div>

    <div class="row">
                 <div class="col-md-6">Title7</div>
                 <div class="col-md-6">Title8</div>
                 <div class="col-md-6">Title9</div>
    </div>

2 answers

  • answered 2019-10-15 17:49 Francisco Santorelli

    Maybe this works, but Im unsure

    <ng-container *ngFor="let p of relatedProperties; let i = index">
       <div class="row" *ngIf="(i + 1) / 3 === 1">
          <div class="col-md-6"  *ngIf="relatedProperties[i - 2].title != null">{{ relatedProperties[i].title }}</div>
          <div class="col-md-6"  *ngIf="relatedProperties[i - 1].title != null">{{ relatedProperties[i].title }}</div>
          <div class="col-md-6"  *ngIf="relatedProperties[i].title != null">{{ relatedProperties[i].title }}</div>
       </div>
    </ng-container>
    

    Also, I gotta say this feels pretty hacky, but if this is what you request, this should work

    edit:

    Note that strict null (a == null) is better than checking for undefined (a === undefined), as it will check for both undefined or null. In your case title != null.

    Also, you could build an iterable that holds the structure you want in a cleaner way.

    instead of having [title1, title2, title3, title4, title5, title6...] you should try to have [[title1, title2, title3], [title4, title5, title6], ...] which is way cleaner and allows you to simply have two *ngFors inside your template

    <element1 *ngFor="let innerArray of myArray; let i = index">
      <element2 *ngFor="let title of innerAray; let j = index">
      </element2>
    </element1>
    

    And finally, I suggest you avoid calling a variable 'p', that's bad practice.

  • answered 2019-10-15 19:33 d-h-e

    If you split your Array into subarrays with always 3 titel's then you can easy loop through this Array in your template.

    https://ng-run.com/edit/zZsztdvTOTpzbUC5Buuj?open=app%2Fapp.component.ts

    component html

    <div class="row" *ngFor="let row of newTitleArr; let i = index">
        <div class="col" *ngFor="let col of newTitleArr[i]">{{ col.title }}</div>
    </div>
    

    component ts

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      titleArr = [
        { title: 'title1' },
        { title: 'title2' },
        { title: 'title3' },
        { title: 'title4' },
        { title: 'title5' },
        { title: 'title6' },
        { title: 'title7' },
        { title: 'title8' },
        { title: 'title9' },
        { title: 'title10' },
        { title: 'title11' },
        { title: 'title12' },
        { title: 'title13' },
      ];
    
      newTitleArr:any[];
    
      ngOnInit() {
         this.newTitleArr = this.splitArr(this.titleArr, 3)
      }
    
      splitArr(arr, size) {
         let newArr = [];
         for(let i = 0; i< arr.length; i += size) {
           newArr.push(arr.slice(i, i+size));
         }
         return newArr;
      }
    }