Angular 2 with *ngFor and ngIf to hide first element

16,259

Solution 1

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

@Component({
	selector: 'app',
	template: `
	  
    <ul *ngFor="let locdata of locations">
   
     <template ngFor let-item [ngForOf]="items"; let-i=index>
          <div *ngIf="item.location==locdata.location">
             <div class="title"> location  {{ item.location}} <span  *ngIf="isNotFirst(item)">  remove </span> </div>
          <div class="container"> {{ item.sedule}}</div>
       </div>
      </template>
	  </ul>
	 
	`
})
export class App {
  items: string[];
  
   isNotFirst(item: any) {
      return this.items.filter(i => i.location === item.location).map(i => i.id).indexOf(item.id) !== 0;
    }
  
  locations:any;
  
  constructor() {
    this.locations=[{location:1},{location:2},{location:3}]; 
    
    this.items = [{
    id:1,
    location:1,
    sedule:1
  },
  {
    id:2,
    location:2,
    sedule:1
  },
  {
    id:3,
    location:1,
    sedule:2
  },
  {
    id:4,
    location:2,
    sedule:2
  },
  {
    id:5,
    location:1,
    sedule:2
  },
  {
    id:6,
    location:2,
    sedule:3
  },  {
    id:7,
    location:3,
    sedule:1
  },
  {
    id:8,
    location:3,
    sedule:2
  },
  {
    id:9,
    location:3,
    sedule:3
  }];
  }
  
}

Solution 2

assume you have a <span> in *ngFor logic, you can use first from *ngFor and show/hide <span> by *ngIf

<div *ngFor="let item in data; let first=first;">
  {{item.attr}}
  <span *ngIf="!first">
    remove
  </span>
</div>

your working plunker.

Solution 3

After doing some deciphering of your template, I think that your basic html for a single item in your items collection looks like:

@Component({
    selector: 'app',
    template: `
      <h4>Syntax 1</h4>
       <div>
          <div class="title"> 
             location  {{ item.location}} 
             <span *ngIf="true">remove</span> 
          </div>
          <div class="container">
             {{ item.sedule}}
          </div>
        </div>
    `
})
export class App { .... }

If that's your basic template for a single item, you can then use *ngFor stamp out multiple versions of this HTML, one for each item in your items collection.

That gives you a template that looks like:

@Component({
    selector: 'app',
    template: `
      <h4>Syntax 1</h4>
       <div *ngFor="let item of items">
          <div class="title"> 
             location  {{ item.location}} 
             <span *ngIf="true">remove</span> 
          </div>
          <div class="container">
             {{ item.sedule}}
          </div>
        </div>
    `
})
export class App { .... }

The final piece to the puzzle is that you only want to show the remove text for a specific item in the collection - namely the first item. Thankfully, ngFor has a solution to this very same problem - you can ask ngFor to tell you the index of the current item in the list of items. You can make use of that index to show or hide the 'remove' text. Since the first item will have an index of 0, then your ngIf test will test against that value.

That gives you:

@Component({
    selector: 'app',
    template: `
      <h4>Syntax 1</h4>
    <ul>
       <div *ngFor="let item of items; let i=index;">
          <div class="title"> 
             location  {{ item.location}} 
             <span *ngIf="i != 0">remove</span> 
          </div>
          <div class="container">
             {{ item.sedule}}
          </div>
        </div>
    </ul>
    `
})
export class App { .... }

Notice the change in the ngFor statement - by using let i=index, you're creating a local template variable i that will be mapped to the current index of the item being output by ngFor. Then you can test against that value to show/hide an element if needed.

(Note that in addition to index, ngFor provides first, last, even and odd variables that you could also make use of. I used index in this example because it has the most wide reaching usage, but you could've easily used first for this use case.

See the documentation for more info about ngFor

Share:
16,259

Related videos on Youtube

B.V.S Bharat Kumar
Author by

B.V.S Bharat Kumar

Addicted to : Angular 1x &amp; 2+ / React JS / TypeScript / JQuery and JavaScript along with C# and SQL Server / Node too. Belongs to one of the user list of Angular2, Angular1, from Hyderabad &amp; India. Connect with me: - GitHub, LinkedIn, Facebook

Updated on August 29, 2022

Comments

  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar about 1 year

    In Angular 2, I got a list of items and based on a given condition (i.e based on location number) I am setting the list to repeat.

    I need to hide the "remove text" for the first box each location.

    Plunker: https://plnkr.co/edit/xtX5BjTBjO61sD2tLwWN?p=preview:

    actual img

    [1]: https://plnkr.co/edit/xtX5BjTBjO61sD2tLwWN?p=preview
    

    import {Component} from '@angular/core';
    
    @Component({
    	selector: 'app',
    	template: `
    	  
        <ul *ngFor="let locdata of locations">
       
         <template ngFor let-item [ngForOf]="items"; let-i=index>
              <div *ngIf="item.location==locdata.location">
                 <div class="title"> location  {{ item.location}} <span  *ngIf="isNotFirst(item)">  remove </span> </div>
              <div class="container"> {{ item.sedule}}</div>
           </div>
          </template>
    	  </ul>
    	 
    	`
    })
    export class App {
      items: string[];
      
       isNotFirst(item: any) {
          return this.items.filter(i => i.location === item.location).map(i => i.id).indexOf(item.id) !== 0;
        }
      
      locations:any;
      
      constructor() {
        this.locations=[{location:1},{location:2},{location:3}]; 
        
        this.items = [{
        id:1,
        location:1,
        sedule:1
      },
      {
        id:2,
        location:2,
        sedule:1
      },
      {
        id:3,
        location:1,
        sedule:2
      },
      {
        id:4,
        location:2,
        sedule:2
      },
      {
        id:5,
        location:1,
        sedule:2
      },
      {
        id:6,
        location:2,
        sedule:3
      },  {
        id:7,
        location:3,
        sedule:1
      },
      {
        id:8,
        location:3,
        sedule:2
      },
      {
        id:9,
        location:3,
        sedule:3
      }];
      }
      
    }
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    please check the plnkr code you will get the main requirement
  • Pengyy
    Pengyy over 6 years
    @B.V.SBharatKumar check the plunker at my answer.
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    check this plnkr you will get main idea
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    we got two location not single
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    for location 2 it removed but for location 1 list it did not
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    please check the link once: we got two location plnkr.co/edit/lu37lt6Y9pe5dlOxXEZx?p=preview
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    please check the link once: we got two location plnkr.co/edit/lu37lt6Y9pe5dlOxXEZx?p=preview –
  • Pengyy
    Pengyy over 6 years
    @B.V.SBharatKumar let me check. wait a moment please.
  • Aman
    Aman over 6 years
    for that it is *ngIf="i !== 0" plnkr.co/edit/28YGcPXWr0QFqFDYcyU4?p=preview
  • Pengyy
    Pengyy over 6 years
    @B.V.SBharatKumar the second one doesn't first for it's not the first element in ngFor. you may consider adding specific index for different locations at your items or create a custom pipe.
  • Pengyy
    Pengyy over 6 years
    @B.V.SBharatKumar check the plunker again, I have build a simple pipe for you to achieve hat you want. hope it helps :)
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    please check we need to hide remove for each location plnkr.co/edit/xtX5BjTBjO61sD2tLwWN?p=preview
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    please check we need to hide remove for each location plnkr.co/edit/xtX5BjTBjO61sD2tLwWN?p=preview
  • B.V.S Bharat Kumar
    B.V.S Bharat Kumar over 6 years
    please check we need to hide remove for each location plnkr.co/edit/xtX5BjTBjO61sD2tLwWN?p=preview
  • Aman
    Aman over 6 years
    added another answer what you are looking for.
  • Pengyy
    Pengyy over 6 years
    @B.V.SBharatKumar did the newest plunker meet what you want? if not, please let me know. :)