Skip to content

How to hide a category when there are no items in it?

I have two arrays in my Angular App, one is an array of object with categories and another array with items which has an object property in it which says to which category the item belong.

So i’ve made some custom pipes, one for which return all items if category “all” is selected and other two pipes for items array which return filtered items for each category and another pipe for search.

The items are rendered with category name when “all” is selected but when i’m searching for an item i would hide the category label if there are no items it it.

How could i archieve it?

Here is my *ngFor where i’m rendering the stuff:

<div
   *ngFor="
   let cat of category
   | menuFiltered
   : (selected === -1 ? -1 : category[selected].id)
   "
   class="products"
   >
   <h2>{{ category.desc }}</h2> // i need to hide this if the below plus array in search is empty
   <hr />
   <div
      *ngFor="
      let plu of plus
      | pluFiltered: men.id
      | pluSearch: searchModel
      "
      class="row mb-3 product"
      >
      ...
   </div>
</div>

EDIT: The arrays looks like this:

menu = [{id: 123, codmen: 2, desc: "ANTIPASTI", estesa: ""}, {id: 127, codmen: 5, desc: "PRIMI", estesa: ""}, {id: 128, codmen: 6, desc: "SECONDI", estesa: ""}] // this is the "category"

plus = [{desc: "SFOGLIATINA AL CARTOCCIO", menu: 123}, {desc: "SFOGLIATINA AL CARTOCCIO", menu: 127}, {desc: "SFOGLIATINA AL CARTOCCIO", menu: 128}] // menu is the actualy id of menu array to which item belong

Once i get the items from my API i’m removing from menu array all objects without any item in it like this:

this.menu = this.menu.filter((menu) =>
  this.plus.some((item) => item.menu === menu.id)
);

And here are my pipes:

menuFiltered pipe:

export class MenuFilteredPipe implements PipeTransform {

  transform(list: any[], menu: number): any {
    return list ? menu === -1 ? list : list.filter(item => item.id === menu) : [];
  }

}

pluFiltered pipe:

export class PluFilteredPipe implements PipeTransform {

  transform(list: any[], menu: number): any {
    return list ? list.filter(item => item.menu === menu) : [];
  }
}

And pluSearch pipe:

export class PluSearchPipe implements PipeTransform {

  transform(list: any[], filterText: string): any {

    return list ? list.filter(item => item.desc.search(new RegExp(filterText, 'i')) > -1) : [];

  }

}

Answer

Try to use a ng-container with a *ngIf:

<div
 *ngFor="let cat of category| menuFiltered: (selected === -1 ? -1 : category[selected].id)" class="products">
  <ng-container *ngIf="plus | pluFiltered: men.id | pluSearch: searchModel as plusArray">
    <h2 *ngIf="plusArray.length > 0">{{ category.desc }}</h2>
     <div *ngFor="let plu of plusArray" class="row mb-3 product">
       ...
     </div>
  </ng-container>
</div>