Executing a single method during the ngAfterViewChecked lifecycle hook in Angular

When tracking a change of variable and wanting to run a function after the change, I utilized the ngAfterViewChecked hook. However, since this method involves data submission which should only occur once, I incorporated a boolean status variable to manage it like so:

    ngAfterViewChecked() 
    {
        //status is a boolean variable which is true
        if (this.status)
        {
           this.status=!this.status;
           this.myFunction();
        }
    }
    myFunction
    {
        //some code
    }

Although, I noticed multiple data submissions and encountered the following error:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for '@dialogContainer': 'enter'. Current value: 'exit'.

I suspect that NgAfterViewChecked is triggered for every change, leading to the issue where if (this.status){} might be executed before the status changes to false.

Is there a solution to resolve this problem?

Answer №1

After spending several hours searching, I successfully found a solution to overcome my issue. Let me explain how I managed to do it.

  • Angular operates in a browser environment where JavaScript is executed. Although JavaScript runs on a single thread, its runtime does not operate on a single thread, so we don't need to worry about it as the Runtime manages this.
  • A Subject in Angular is an observable that can emit values to multiple observers listening to it.
  • A Subscription in Angular can store an observable for later use.

To begin, I created a Subject named paymentListener, an integer variable called counter, and a Subscription named oneTimePayment.

oneTimePayment: Subscription;
private paymentListener = new Subject<number>();
counter = 0;

Within the onInit method, I established a subscription.

ngOnInit() {
    
    this.oneTimePayment = this.paymentListener.subscribe((counter) => {
          if (counter == 1) {
            // Call my function here
            this.myFunction();
          }
        });
    
    }

In the ngAfterViewChecked lifecycle hook, I utilized the paymentListener (a Subject) to emit the counter value.

ngAfterViewChecked() {
    if (this.counter == 0) {
      this.counter++;
      if (this.counter == 1) {
        this.paymentListener.next(this.counter);
      }
    }
  }

The value is only emitted by the paymentListener (Subject) when the counter equals 1. Therefore, the subscription made in onInit will receive the emitted value, triggering the execution of myFunction only when the emitted value is 1. This ensures the method runs once after a change.

Lastly, remember to call unsubscribe inside ngOnDestroy to prevent memory leaks.

ngOnDestroy() {
    this.oneTimePayment.unsubscribe();
  }

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

Using a function from one class within another class by passing it as a prop

Below are the methods found in my Search.tsx class. renderSuggestion(suggestion) { <div className="buttons"> <button className="button">View Location</button> <button className="button whitebutton" onClick={this.h ...

Preserving variable values across page transitions in Angular 2

I am facing an issue with my multi-page website that uses a router. I want to pass a variable value from one page to another. Here is the code snippet from my contact form page: testName:string = "hello"; ngOnInit() { this.dataService.Stream ...

Do I have to wait for the HTTP get request to access the fetched object property?

I am currently working with Angular and TypeScript on a dish-detail component that is accessed through 'dishes/:id' The dish object returned has a property called components, which contains an array of objects with two properties: id: type stri ...

Is there a way to substitute the HOC with a single call and solely modify the prop?

One issue I've encountered in my project is the repetitive use of a Higher Order Component (HOC) for the header. Each time it's used, the props are set to determine whether header links should be displayed or not. My objective is to streamline th ...

Enhance your app with the seamless navigation experience using Ionic 2

As a beginner in Angular2, Ionic2, NodeJS ... I am experimenting with writing some code to learn. In my journey, I attempted to create a screen with 3 tabs and a menuToggle. When the application is launched, clicking the menuToggle button on the first tab ...

Displaying values from TypeScript to the view in Angular 5

When using basic HTML and JS, the following code functions correctly: // main.js function videoHTML(videoNumber, trackName, trackType = 'srt') { return '<video id="video-js" class="video-js vjs-default-skin" ' +'controls p ...

What is the proper way to supply a header parameter in Angular?

Encountering difficulties when trying to pass my header parameter in Angular. The error I'm receiving from my API states "Session Id is required" as shown below. Here is the endpoint: [HttpDelete("")] public IActionResult EndSession( ...

Angular 8: A Guide to Updating Tags in innerHTML

Hello, below is the code I am working with: <span [innerHtml]="question.description | SafePipe: 'html'" style="font-weight:500;" class="ml-1"></span> Upon inspecting my website, I noticed that my <span> tag contains nested &l ...

Error encountered on Firefox browser when saving content in TinyMCE editor: NS_ERROR_UNEXPECTED

We are currently experiencing an issue on the Firefox browser where our component with the tiny-mce editor displays an NS_ERROR_UNEXPECTED message and does not show any content upon reloading. Initially, when the editor loads for the first time, the conte ...

Creating a TypeScript mixin with a partial class is a useful technique that allows you to

I am attempting to have class A inherit properties from class B without using the extends keyword. To achieve this, I am utilizing a mixin in the following manner: class A{ someProp: String someMethod(){} } class B implements classA{ someProp: String ...

The Next.js template generated using "npx create-react-app ..." is unable to start on Netlify

My project consists solely of the "npx create-react-app ..." output. To recreate it, simply run "npx create-react-app [project name]" in your terminal, replacing [project name] with your desired project name. Attempting to deploy it on Netlify Sites like ...

Having difficulty reaching the specified route ID in Angular app

I'm encountering an issue when attempting to navigate to a route with an ID argument using the router. Here's the code snippet from my component: import { Router } from '@angular/router'; ... constructor(private router: Router) { } .. ...

Retrieve a user by their _id, remove a user using their _id, and modify a user based on their _id using Next.js 14, utilizing Typescript

I'm currently troubleshooting three request methods that are not functioning properly: GET, UPDATE, and DELETE for a user by _id. When I try to run these requests in the browser or postman, I receive a "no page found" error in the API call. The rout ...

What is the best way to delete a purchase event that is being displayed on my webpage through Google Tag Manager?

Lately, I noticed that Google Tag Manager has been displaying a purchase event on my html. The data appears to be from a sample in development and I can't figure out why it's showing up below the footer of my page. Does anyone have any insight i ...

Disable all typings within a specified namespace for a specific file

I need to disable typechecking for a specific namespace called MyNamespace in a Typescript file. Is there a way to achieve this without affecting other files? ...

Ensuring that the field remains active in Angular2 even after editing it with a value

When the 3rd dropdown value is selected in the first field dropdown, it enables the 2nd field. However, when I edit and change a different value, since the 2nd field is disabled, I receive null or undefined as the value. I want the 2nd field to retain its ...

Develop a fresh Typescript-driven sql.js database

I'm in the process of converting my JavaScript code to TypeScript. One of the libraries I rely on is sql.js. I have successfully installed the corresponding typing for it, but I am facing a roadblock when it comes to creating the database. Here is ho ...

Issues with Typescript when Adding Objects to an Array in a Function

In my Angular 2 application, I am encountering a problem when trying to add new items to an array. The issue appears to be related to Typescript types, although I'm not entirely certain. Here is the current structure of the array I am attempting to mo ...

Exporting custom type definitions using a node module

In my project, I have a module named module_core with a specific directory structure as shown below: /src /company /webservices /service-one ... /service-two ... /service-new // my service i ...

Server.js experiencing issues with body-parser causing backend to fail loading in browser

Having an issue with my backend server not loading in the browser. It runs fine in terminal, but I can't seem to figure out why it's not working in the browser. I'm new to backend programming and I recently added an app.post method which see ...