Displaying and concealing a subcomponent within a parent element for a set duration of time

I have a notification component that is displayed as a child component in the parent component after a button click. It automatically hides after a certain number of seconds. Here is the code I have developed:

MyCode

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 component:

<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)
  }

The functionality works well, but I am facing an issue where if the initial notification has not finished hiding after 3 seconds and I click the button again, the new notification does not display. Can someone help me identify what I am doing wrong? I am still learning Angular.

Additionally, I would like to achieve the same behavior for both instances of the child component.

Answer №1

To fix the issue, you need to restructure your code by moving the timeout functionality outside of the ngOnChanges method. Utilizing a setter in your component setup can achieve this.

@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;
    // Implement a failsafe mechanism if expected values are not set
    if (value && this.duration) {
      this._show = true;
      setTimeout(() => {
        this._show = false;
      }, this.duration);
    }
  }
  get show(): boolean {
    return this._show;
  }

  private _show = false;
}

An alternative workaround is presented below, although it may not be the most elegant solution:

@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);
  }
}

Implementing RxJS Observables could provide a cleaner solution, but it might be more complex for newcomers to Angular.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Struggling to retrieve Json data through Ajax in Rails 5

Hey there! I'm currently exploring the world of Rails action controllers with Ajax, and I've run into a bit of a snag. I can't seem to retrieve Json data and display it in my console.log using my Ajax function. The GET method works perfectly ...

Steps to initiate a PDF file download when a button is clicked using Angular 6

I need assistance with downloading the .pdf file when clicking a button. Below is the code I am currently using: downloadMyFile() { const link = document.createElement('a'); link.setAttribute('target', '_blank&apos ...

MongoDB Node.js throws a RangeError when trying to push a message that exceeds the maximum call stack size

I'm currently delving into the world of building a MEAN app and encountering an issue when attempting to append a message to a messages array within my User Model. While I can successfully create a new message and pass the user object, I face an error ...

Stop the span within the paragraph from breaking onto a new line

I have a situation where I need quote symbols to be placed inside span elements that are children of a p element. Each quote symbol requires slightly different CSS styles, and they must be included in the HTML rather than in the CSS due to backend restrict ...

The elusive axios was nowhere to be found, not in the project itself nor in any of the directories, including

I am currently working on a mobile app using react native, and I am facing an issue while trying to import Axios. Even though I have installed Axios and everything seems fine, I keep getting the following error: Android Bundling failed 1097ms Unable to r ...

What is the best method for swapping out Angular2 Http for uploading files?

When attempting to send a file from an Angular2 app, the REST API often fails to recognize the file in the request it receives. Despite the content appearing to be present, there seems to be a disconnect. After extensive research on platforms like StackOv ...

There was an error caught: the object is not a function, specifically the button inside a form

Here is a snippet of code from my jsp page: <form name="programarRutasForm" method="post" action="/SGT_Galp_web/programarRutas.do"> <table> <tr> <td> <input type="button" name="insereVuelta" ...

When using Node.js, React.js does not recognize raw HTML strings as valid HTML elements

I successfully sent raw HTML from node.js to react, but when I try to render it, the content is displayed as a raw string instead of HTML elements. This is how I retrieve the string in the front-end: componentDidMount() { this.callApi() .then( ...

What are the steps to develop an ElectronJS application that displays "Hello world!" in the console after a button click?

Can anyone offer a helping hand? From the depths of imagination to the realms never before conceived by humans. Check out this HTML snippet: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hell ...

Hiding a HubSpot form is made easy with the utilization of vue.js and its

Struggling with using vue's v-show to toggle between two hubspot forms based on website locale/language (using vue i18n). The navbar controls language switching. Currently, both forms always show or both are hidden. Even after trying vuex, the issue ...

Running multiple instances of setTimeout() in JQuery

I'm looking for a way to delay the execution of 10 lines of independent jQuery code with 2 seconds between each line. I initially tried using setTimeout() on each line, but is there a more elegant solution for this scenario? The jQuery DELAY method do ...

Looking for a way to choose a button with a specific class name and a distinct "name" attribute using jquery?

I am currently working on developing a comment system. As part of this system, I want to include a toggle replies button when a user posts a reply to a comment. However, I only want this button to be displayed if there are no existing replies to the commen ...

Trouble with the navbar collapse functionality in Bootstrap

3 I made some changes to the navbar, now the navbar-header is showing but the collapse navbar-collapse is not. Here is my code. Can you spot where I went wrong? <nav class="navbar navbar-default"> <div class="container-fluid" ...

I need the links to open up the content area on the website in HTML

Is it possible to have a fixed header that does not disappear when clicking links from the navigation bar? I tried dividing the page into tables to achieve this. Now, I want to open the links in the navigation bar in the right column (the main content col ...

What is the optimal method for showcasing functions in NodeJS?

In my project, I have a directory specifically for all my DAO files. These DAO files are responsible for interacting with the MySQL server. The structure of my DAO directory includes: | -- dao | -- user.dao.ts | -- employee.dao.ts Additionally, I hav ...

What is the process for reversing the bubble order of elements in JavaScript?

I've developed a custom Slider component that performs flawlessly, with one small hiccup. When the slider is located within a modal, the mouseUp event triggers on elements beneath it (in terms of z-index) before reaching the element itself. This beh ...

Transferring information from one website to another

I need to transfer content from one website to another while maintaining good SEO practices. Using Iframes is not an option, and PHP won't work in the CMS I'm using. I attempted a different approach: $('#target-div').load('http:/ ...

Guidelines for positioning social media icons to the right of the collapsible navigation bar in Bootstrap 3

I am having trouble aligning my social media icon with the navbar menu to the right. There seems to be a gap when I try to do it. The social icon is currently in a separate row, while the navbar is also in a separate row. I just want to align them both to ...

Exploring the wonders of array filtering and reducing in Javascript

Can someone help me turn an array of voter objects into a count of how many people voted? I'm just starting to learn JavaScript and feeling confused with the reduce and filter methods. When I run the code, I get undefined @@ function totalVotes(a ...

Capturing Screenshots with Ionic Framework

I am currently working on an Ionic application that utilizes geolocation via the Google API. However, I am facing a challenge with implementing a feature where a button in the upper right corner should take a screenshot and trigger a popover with options t ...