Issue
I have notification component, which is a child component and being shown in parent component after a button click. After a custom seconds of time it will be hidden. So far I have come up with this code (Stackblits).
Parent component:
<button (click)="handleClick()">Initiate Message</button>
<app-notification [message]="message" [duration]="3000" [show]="show"></app-notification>
<app-notification [message]="message" [duration]="6000" [show]="show"></app-notification>
export class AppComponent  {
   message:string;
   show:boolean;
  handleClick(){
    this.message = 'Good Morning';
    this.show=true;
  }
}
Child comp:
<div class="container" *ngIf="show">
  {{ message }}
</div>
 @Input() message: string;
  @Input() duration: number;
  @Input() show = false;
  constructor() {}
  ngOnChanges(changes: SimpleChanges) {
    console.log(this.show)
    setTimeout(()=>{
      this.show = false;
      console.log(3)
    }, this.duration)
  }
This works perfectly, but after 3 seconds as it is in the example, If I click the button, the child component is not being showed. What am I doing wrong. I am new to Angular, please help me.
Also I want to handle the same for both instances of the child.
Solution
You have to move the code for the timeout out of ngOnChanges.
In your component setup a setter would do the trick.
@Component({
  selector: 'app-notification',
  templateUrl: './notification.component.html',
  styleUrls: ['./notification.component.css'],
})
export class NotificationComponent {
  @Input() message: string;
  @Input() duration: number;
  @Input() set show(value: boolean) {
    this._show = value;
    // Or find another failsafe if the values are not set as expected
    if (value && this.duration) {
      this._show = true;
      setTimeout(() => {
        this._show = false;
      }, this.duration);
    }
  }
  get show(): boolean {
    return this._show;
  }
  private _show = false;
}
As well as an ugly hack to avoid Angular not realizing that this value needs to be reset:
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  message: string;
  show: boolean;
  duration: number;
  handleClick() {
    this.message = 'Good Morning';
    this.show = true;
    setTimeout(() => (this.show = false), 1);
  }
}
Using RxJS Observables would solve this problem in a nice way, but it would also be more complicated if you are new to Angular.
Answered By - Leon Hikari
 
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.