Tips for effectively implementing ngIf on material input within a child component to avoid encountering the ExpressionChangedAfterItHasBeenCheckedError

The issue

Encountering an

ExpressionChangedAfterItHasBeenCheckedError
error while using a PasswordComponent with ng-template. Specifically, wanting to conditionally bind the errorStateMatcher only when
controlName === 'confirmPassword'
.

To view the complete code causing the problem, visit here. Look inside password.component.html for the troublesome ng-template:

  <template *ngIf="controlName === 'confirmPassword'; then Custom else Default"></template>
  <ng-template #Custom>
    <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>
  </ng-template>
  <ng-template #Default>
    <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/>
  </ng-template>

Note: Even without the ng-template, placing the ngIf directly on the input element still triggers the same error. Initially believed to be associated with ng-template but it's actually related to ngIf.

The Error

The mat-error values are inconsistent and occasionally display aria-describedby: null.

PasswordComponent.html:4 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression changed after it was checked. Previous value: 'aria-describedby: mat-error-3'. Current value: 'aria-describedby: mat-error-4'.

Error Reproduction Steps

  • Enter text in password field
  • Switch focus back to username input
  • Return focus to password input
  • Edit or remove characters to change the mat-error message
  • Console will show
    ExpressionChangedAfterItHasBeenCheckedError

Answer №1

Here are some suggestions to try:

  <input #Custom *ngIf="controlName === 'confirmPassword'; else Default" matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>

<ng-template #Default> 
        <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/> 
    </ng-template>

UPDATE

In essence, the issue may be caused by a child template using a parent value that changes after the child is rendered. This typically occurs because children are rendered before parents finish rendering. Initially, it seemed related to placing the errorStateMatcher directive in a child template.

Please refer to this article for a comprehensive explanation and solutions to common patterns causing this problem:

UPDATE

Building on your feedback, there might be a conflict between the ngIf directive and the matInput directive. You can attempt the following modification:

<ng-container *ngIf="controlName === 'confirmPassword'; else Default">
    <input #Custom matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>
</ng-container>
<ng-template #Default> 
    <input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/> 
</ng-template>

You can view a functional example here: StackBlitz Example

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

What is the best way to postpone the rendering of a table?

My table is bogged down by an excessive number of rows, causing a sluggish rendering process. I'm curious about the best method to address this issue. Are there any existing libraries specifically designed for this purpose? ...

What is the process for launching my Angular 8 application on an Apache server running Ubuntu 18?

I am looking for a way to showcase my compiled "dist" folder, which was generated on a Windows system using the command "ng build --prod", on an Ubuntu 18 server that is running Apache. Any suggestions on how I can achieve this? ...

Creating identical dropdown filter options from API in React.js

My dropdown menu is experiencing an issue where it is showing duplicated values from the API. When I receive documents from the backend, some of them have the same name, resulting in duplication in my dropdown list. Here is a snippet of my code: The funct ...

items within an unordered list that can be collapsed

Answer: Nikhil was on the right track with his solution, but I had to make some modifications. Specifically, I needed to create and initialize an empty array to display the details properly. Here's the updated code: if (this.name.toLowerCase() == va ...

Is there a way to prevent users from right clicking on all links with the same class using js/jquery?

Rails 4 + JS + jquery Is there a way to disable right click on links with the same class in Rails? <% @schedule_hash.values.each do |schedule| %> <%= link_to "Cancellation policy", {:controller => 'web', :action => 'get ...

Implement a universal JavaScript UI library into an Angular application

For my Angular application (Angular4.x), I am using the mapwize sdk which is a pure javascript library. I have successfully displayed a MapWize map by including the necessary scripts and styles in the index.html file, as shown below: <head> ...

Adding a FirebaseListObservable and implementing the use of endAt

In my Angular 4 chat app, I am implementing a 'lazy loading' feature for messages using Firebase as the dataset. The current approach involves fetching a fixed number (currently set to 3 for testing) of messages when the app initially loads, and ...

The isAuthenticated status of the consumer remains unchanged even after being modified by a function within the AuthContext

I am working on updating the signout button in my navigation bar based on the user's authentication status. I am utilizing React Context to manage the isAuthenticated value. The AuthProvider component is wrapped in both layout.tsx and page.tsx (root f ...

Issue with jQuery's outerHeight() function persisting despite attempting to fix it with jQuery(window).load()

Once the content is loaded using AJAX, I need to retrieve the outerHeight of the loaded elements. Ajaxload file: $('#workshop').submit(function(event){ $.ajax({ url: URL, type: 'POST', data: $(' ...

Is there a way for me to retrieve the element that is linked to the ng-disabled attribute?

Is there a way to access the element with the ng-disabled attribute inside the function without passing it as a parameter? Here is the HTML element: <input class="needsDisabling" ng-disabled="isFieldDisabled()" type="text"> The isFieldDisabled fu ...

The rendering of a template as a variable is not supported by EJS

Here's the structure of my project: index.js views ------partials --------login --------footer ------pages ---------index Currently, I am rendering index.ejs using this code: res.render('pages/index& ...

Exploring the world of AngularJS 1.3 with the exciting anticipation of the upcoming release of Angular 2 in just one year

Currently contemplating learning AngularJS 1.3, but concerned about the upcoming release of version 2 and the significant changes that will come with it. Is it worth investing time and effort into mastering a framework that is soon to be obsolete? Seekin ...

Is there a way to implement an onclick event for every iframe within a document using jquery?

I have a webpage containing two iframes that can be switched using a selector. My goal is to implement an onclick event that will trigger a URL for specific <rect> elements within the iframes. After reading a helpful post on accessing iframe childr ...

Ways to specify the styles for tr, td, and label elements within a material table

Hey there! Currently, I'm working with material table in react. I came across this page: https://material-table.com/#/docs/features/styling, where it mentions that we can use cellStyle, headerStyle. But what if I want to add more detailed styles to e ...

Is this method an effective way to create global states across React components?

After delving deep into props-drilling while coding a full-fledged web application with React, I've decided to explore using React 'contexts'. Following the guidelines in the React documentation, I am implementing an approach to make my stat ...

Troubleshooting issue: pesky popper.js error arises when integrating Bootstrap 4 into the Require

As I integrate Bootstrap 4 into my RequireJS configuration for my application, a warning arises: An error occurred while loading the resource from: “”. accompanied by this error message: Error: Script error for "popper.js", required by: bootst ...

Angular 2 - Unable to access the AssetUrl property due to undefined value

Just getting started with angular2 and material-design. Attempting to integrate the two. I decided to clone this material2-app, which is built on angular2 and material2 and ran npm install. However, when I tried running npm start to start a server, I enc ...

"Using a function parameter as a key in a JSON object

While I may not be a JSON expert, I am struggling to understand why this code is not functioning as expected and what steps I need to take to fix it. Despite my efforts to search for solutions, I suspect that my lack of familiarity with the correct termino ...

Submitting a form that includes an <input type="file"/> in Angular 2: Best Practices

media.html <form #form="ngForm" (ngSubmit)="uploadFile(form.value)"> <input type="file" ngControl="inputFile" /> <input type="text" ngControl="name"/> <button type="submit" >Upload</button> </form> media.ts uplo ...

How can we verify the validity of URLs based on their length, presence of capital letters, and specific whole words?

I'm currently working on a piece of code that verifies the URL provided by users during sign-up for my application. I want to implement the following restrictions: URL must be at least 3 characters long No capital letters allowed Avoid certain words ...