196
votes

I'm having a problem hiding and showing an element depending of a boolean variable in Angular 2.

this is the code for the div to show and hide:

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>

the variable is "edited" and it's stored in my component:

export class AppComponent implements OnInit{

  (...)
  public edited = false;
  (...)
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }, 3000);
  }
}

The element is hidden, when saveTodos function starts, the element is shown, but after 3 seconds, even if the variable come back to be false, the element does not hide. Why?

10

10 Answers

185
votes

You should use the *ngIf Directive

<div *ngIf="edited" class="alert alert-success box-msg" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>


export class AppComponent implements OnInit{

  (...)
  public edited = false;
  (...)
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);
  }
}

Update: you are missing the reference to the outer scope when you are inside the Timeout callback.

so add the .bind(this) like I added Above

Q : edited is a global variable. What would be your approach within a *ngFor-loop? – Blauhirn

A : I would add edit as a property to the object I am iterating over.

<div *ngFor="let obj of listOfObjects" *ngIf="obj.edited" class="alert alert-success box-msg" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>


export class AppComponent implements OnInit{
   
  public listOfObjects = [
    {
       name : 'obj - 1',
       edit : false
    },
    {
       name : 'obj - 2',
       edit : false
    },
    {
       name : 'obj - 2',
       edit : false
    } 
  ];
  saveTodos(): void {
   //show box msg
   this.edited = true;
   //wait 3 Seconds and hide
   setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);
  }
}
209
votes

There are two options depending what you want to achieve :

  1. You can use the hidden directive to show or hide an element

    <div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
    
  2. You can use the ngIf control directive to add or remove the element. This is different of the hidden directive because it does not show / hide the element, but it add / remove from the DOM. You can loose unsaved data of the element. It can be the better choice for an edit component that is cancelled.

    <div *ngIf="edited" class="alert alert-success box-msg" role="alert"> 
      <strong>List Saved!</strong> Your changes has been saved.
    </div>
    

For you problem of change after 3 seconds, it can be due to incompatibility with setTimeout. Did you include angular2-polyfills.js library in your page ?

37
votes

When you don't care about removing the Html Dom-Element, use *ngIf.

Otherwise, use this:

<div [style.visibility]="(numberOfUnreadAlerts == 0) ? 'hidden' : 'visible' ">
   COUNTER: {{numberOfUnreadAlerts}} 
</div>
16
votes

For child component to show I was using *ngif="selectedState == 1"

Instead of that I used [hidden]="selectedState!=1"

It worked for me.. loading the child component properly and after hide and un-hide child component was not undefined after using this.

8
votes

This is a good use case for an Angular Directive. Something like this is surprisingly useful.

@Directive({
  selector: '[removeAfter]'
})
export class RemoveAfter {
  constructor(readonly element: ElementRef<HTMLElement>) { }
 
  /**
   * Removes the attributed element after the specified number of milliseconds.
   */
  @Input() removeAfter: number;

  ngOnInit() {
    setTimeout(() => {
      this.element.nativeElement.remove();
    }, this.removeAfter);
  }
}

Usage:

<div [removeAfter]="3000">Removed after 3 seconds</div>
5
votes

We can do it by using the below code snippet..

Angular Code:

 export class AppComponent {  
    toggleShowHide: string = "visible";  
 }

HTML Template:

  Enter text to hide or show item in bellow: 
  <input type="text" [(ngModel)]="toggleShowHide">
  <br>
  Toggle Show/hide:
  <div [style.visibility]="toggleShowHide">   
     Final Release Angular 2!
  </div>
4
votes

Depending on your needs, *ngIf or [ngClass]="{hide_element: item.hidden}" where CSS class hide_element is { display: none; }

*ngIf can cause issues if you're changing state variables *ngIf is removing, in those cases using CSS display: none; is required.

0
votes

@inoabrian solution above worked for me. I ran into a situation where I would refresh my page and my hidden element would reappear on my page. Here's what I did to resolve it.

export class FooterComponent implements OnInit {
public showJoinTodayBtn: boolean = null;

ngOnInit() {
      if (condition is true) {
        this.showJoinTodayBtn = true;
      } else {
        this.showJoinTodayBtn = false;
      }
}
0
votes

Just add bind(this) in your setTimeout function it will start working

setTimeout(function() {
       this.edited = false;
       console.log(this.edited);
   }.bind(this), 3000);

and in HTML change

<div *ngIf="edited==true" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>

To

<div *ngIf="edited" class="alert alert-success alert-dismissible fade in" role="alert">
        <strong>List Saved!</strong> Your changes has been saved.
</div>
0
votes

In TS file

showMyContainer: boolean = false;

In HTML

<button (click)="showMyContainer=!showMyContainer">Show/Hide</button>

<div *ngIf="showMyContainer">
     your code
</div>

See my stackblitz

Happy to hear if someone got helped.