Joel
Joel

Reputation: 1064

Angular ngFor. How to display a header conditionally?

I have a Observable array (returned from a firebase query) of apartment objects ordered by apartment number:

[
  {number: 10, color: white, ...},
  {number: 11, color: blue, ....},
  {number: 20, color: red, ...}
  {number: 32, color: red, ...}
]

Each apartment has a number.

The first digit of a apartment number determine his flor.

Example:

Apartment number: 32 = 3th floor
Apartment number: 53 = 5th floor

I need to display a header with floor number each time that floor change. Some like this:

1th Floor:
 - 10
 - 11
 - 12
 ...
2th Floor:
 - 20
 - 21
 ...
3th Floor:
 - 30
 - 31
....

How can I do this using ngFor with async pipe?

To simple display a list of all apartments I'm using the code bellow:

<div *ngFor="let apartment of apartment$ | async">
<h2>{{apartment.number}}</h2>
</div>

Upvotes: 2

Views: 1655

Answers (3)

Eliseo
Eliseo

Reputation: 57971

If you want calculate the floors you can make

//Add to each this.apartments element a property:floor
this.apartments=this.apartments.map(ap=>
  {
    return {...ap,floor:Math.floor(ap.number/10)}
  })

//Create an array with unique values of "floor"
//And add the property "apartments" 
const floor=this.apartments.filter((item, pos)=> {
    return this.apartments.findIndex(i=>item.floor==i.floor) == pos;
}).map(f=>{
  return{
    floor:f.floor,
    apartments:this.apartments.filter(a=>a.floor==f.floor)
  }

}

Upvotes: 1

Sebastian Hildebrandt
Sebastian Hildebrandt

Reputation: 2781

If you want to do this just with some template logic (and using async), you can take advantage of the index property of *ngFor:

<div *ngFor="let apartment of apartments | async; let i = index">
    <h1 *ngIf="i === 0 || (apartment.number / 10 >> 0) !== (apartments[i-1].number / 10 >> 0)">{{(apartment.number / 10 >> 0)}}th Floor {{apartment.number}}</h1>
    <h2>{{apartment.number}}</h2>
</div>

where (apartment.number / 10 >> 0) should give the number divided by 10 without remainder ...

Upvotes: 0

Akj
Akj

Reputation: 7231

Here is working Example Working Example

ts code:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  floor: any[] = [];
  apartments: Array<any> = [
    { number: 10, color: "white" },
    { number: 11, color: "blue" },
    { number: 20, color: "red" },
    { number: 32, color: "red" },
    { number: 33, color: "red" },
    { number: 34, color: "red" }
  ];



  constructor() {
    for (let i = 0; i < this.apartments.length; i++) {
      this.calculateFloor(this.apartments[i]);
    }
  }
 calculateFloor(apartment){
     if (Math.floor(apartment.number / 10) > 0) {
      if (this.floor.indexOf(Math.floor(apartment.number / 10)) == -1) {
        this.floor.push(Math.floor(apartment.number / 10));
      }
      return { num: apartment.number, status: true, floor: Math.floor(apartment.number / 10) };
    }

  }

  calculateApartment(apartment, floor){
    if (Math.floor(apartment.number / 10) == floor) {
      return true
    } else {
      return false
    }
  }
}

HTML:

<div *ngFor="let f of floor;">
    <h1>{{f}} th Floor</h1>
    <li>
        <ul *ngFor="let apartment of apartments">
            {{calculateApartment(apartment, f)? apartment.number: ''}}
        </ul>
    </li>
</div>

Upvotes: 1

Related Questions