Error: The value of the expression has been altered after it was already checked. Initial value was 'undefined'. An exception has occurred

Although this question has been asked multiple times, I have read similar issues and still struggle to organize my code to resolve this particular exception.

Within my component, there is a property that dynamically changes based on a condition:

public emailToValue: string

Inside my HTML file, users have the ability to manually add a new row, triggering a pipe to set the value assigned in the component:

<ng-container matColumnDef="emailTo">
<mat-header-cell *matHeaderCellDef mat-sort-header>Email To</mat-header-cell>
<mat-cell *matCellDef="let userMarket">
{{ userMarket | formatEmailTo : emailToValue}}
<input type="text"  matInput [value]="userMarket.emailTo">
</mat-cell>
</ng-container>

This pipe sets a default email to be displayed in the new row if the email is null or undefined:

  @Pipe({
  name: 'formatEmailTo',
})
export class FormatEmailPipe implements PipeTransform {
  public transform(userMarket: UserMarketDTO, email: string): void {
    if (_.isNil(userMarket.emailTo)) {
    userMarket.emailTo = email;
    }
  }
}

The functionality works correctly, but an exception occurs each time a new row is created:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'value: undefined'. Current value: 'value: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b9caccc9d6cbcdf9caccc9c9d6cbcd97dad6d4">[email protected]</a>'.

Any assistance would be greatly appreciated.

Thank you.

Answer №1

Here are a couple of points to consider:

  1. The functionality only works in develop mode where change detection runs twice. If you encounter that error, it means that the initial value of undefined would have been displayed on the front end in production.
  2. Using a pipe may not be the best approach in this scenario. Typically, a pipe is used to transform and return a value needed by the HTML. It seems like defaulting the email value when the row is added might be a better solution.

However, if there is a specific requirement necessitating this method and you wish to avoid using ChangeDetectorRef, I have a potential solution for you. Please refer to my StackBlitz example:

Employ a template reference for the column with an already piped UserMarketDTO:

<ng-template #emailCell let-userMarket>
  {{ userMarket.email }}
  <input type="text" matInput [value]="userMarket.email">
<ng-template>

And here is the column definition where the piping takes place:

<!-- Email Column -->
  <ng-container matColumnDef="email">
    <th mat-header-cell *matHeaderCellDef> Email </th>
    <td mat-cell *matCellDef="let element">
      <ng-container *ngTemplateOutlet="emailCell; context: { $implicit: element | formatEmailTo: defaultEmailValue }"></ng-container>
    </td>
  </ng-container>

Additionally, remember to update the pipe to ensure it returns the modified UserMarketDTO:

public transform(userMarket: UserMarketDTO, defaultEmail: string): UserMarketDTO {
    if (!userMarket.email) {
      userMarket.email = defaultEmail;
    }
    return userMarket;
  }

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

Navigating Dynamically between tabs - A How-to Guide

I am working on a mat-tab Angular app where I need to dynamically generate links and transfer them to a navLinks object. Despite ensuring that the concatenation is correct, it seems like my approach is not working as expected. Here's a glimpse of what ...

What causes the typescript error in my code: The argument being passed is either a string, an array of FilterData, an array of numbers, or an array of Moments, which is not compatible with a parameter of type 'string'?

When writing my code, I have the need to utilize various types for different scenarios. Depending on the situation, the type may be a string, number[], FilterData[] (a custom type), or Moment[]. To address this requirement, I defined the type as: export ty ...

What is the best way to add a 'Drawer' component into the 'AppBar' using React MUI within the Next.js framework?

My goal is to create an App bar with a 'hamburger' icon on the left that, when clicked, will display a Sidenav (drawer). I am working with React Material and Next.js (App router) and need to have the app bar and drawer as separate components, hea ...

Creating a unique type with a suffix of `px`

Understanding how to create a Position type class is clear: class Position { x: number = 0; y: number = 0; } However, I now require the x and y values to be integers with the suffix of px, like this: const position = { x: '1px', y: &ap ...

Is ZSH in Ubuntu having trouble with Angular, Sails.js, or LoopBack?

When attempting to install JavaScript frameworks like Angular, LoopBack, or SailsJS, I encountered an issue with ZSH. I am unable to run commands to build the projects as they are not recognized in ZSH. How can I include them, such as: ng new App sails n ...

Child component responsible for closing the modalI will guide you through

A component in my project has a header with a modal window that pops up when clicked: <a (click)="open(content)" class="in">Sign in</a> <ng-template #content let-modal> <button type="button" class="close" aria-label="Close" (click)= ...

The bubble test encountered an error while attempting to install npm

Every time I run npm install, the installation process goes smoothly until the very end, where this error suddenly pops up: npm ERR! 436 passing (12s) npm ERR! 3 pending npm ERR! 2 failing ... I'm currently working on an Angular App and even af ...

Creating a .d.ts file for a JavaScript file that exports a plain object - tips and best practices

I am attempting to include a .d.ts file for an existing js file. The type.js file looks like this: // type.js export default { NORMAL: '001', CHECK: '002', }; Now, I have added a type.d.ts file as follows: // type.d.ts decla ...

How to use multiple template urls in Angular 6

Currently, I am creating a front-end using Angular 6 and facing the challenge of having components with varying html structures based on the user who is logged in. The number of templates required can range from 2 to over 20, so my preference would be to ...

Is there a way to showcase the data of each table row within the tr tag in an Angular 8 application?

I have been developing an application using Angular 8. The employee-list component is responsible for presenting data in a table format. Within the employee-list.component.ts file, I have defined: import { Component } from '@angular/core'; impo ...

What is the injection token used for a specialized constructor of a generic component?

I created a versatile material autocomplete feature that I plan to utilize for various API data such as countries, people, and positions. All of these datasets have common attributes: id, name. To address this, I defined an interface: export interface Auto ...

A step-by-step guide on sending a fetch request to TinyURL

I have been attempting to send a post request using fetch to tinyURL in order to shorten a URL that is generated on my website. The following code shows how I am currently writing the script, however, it seems like it's not returning the shortened URL ...

What are the steps to update data using Angular?

I am currently working on a project to create a simple webpage that allows users to add values to a database. The database only contains an ID and a value, which should also be displayed on the page. Although my code is functioning correctly and I can suc ...

tsconfig is overlooking the specified "paths" in my Vue project configuration

Despite seeing this issue multiple times, I am facing a problem with my "paths" object not working as expected. Originally, it was set up like this: "paths": { "@/*": ["src/*"] }, I made updates to it and now it looks like ...

Tips for ensuring the correct typing of a "handler" search for a "dispatcher" style function

Imagine having a structure like this: type TInfoGeneric<TType extends string, TValue> = { valueType: TType, value: TValue, // Correspond to valueType } To prevent redundancy, a type map is created to list the potential valueType and associate i ...

Injecting pipes into directives in Angular: A guide

I've developed a custom directive that formats input values based on the provided pipe parameter (@Input) in Angular reactive forms. For this functionality, I had to import the necessary pipes (currently just one) and implement a switch mechanism to ...

Does Angular 8 development mode implement tree-shaking?

I am curious to know if tree-shaking occurs during Angular 8 development mode. When running the following command: ng build I understand that tree-shaking happens when I use the command below: ng build --optimization=true|false ...

Ways to access or modify variables from a different component in Angular 4 without relying on a service class

Is there a way to interact with or modify variables in another component without using a shared service? I'm dealing with two separate components in my Angular project. Keep in mind that these components are not related as Parent and Child. Compone ...

Blazing Paths with an Isomorphic Application Using Inferno and TypeScript

I am currently working on building an isomorphic application using Express and Inferno. Strangely, I have not come across any similar projects online. In my attempt to create one myself by following a guide on Razzle, specifically related to Inferno, I enc ...

Angular2 is throwing a Typescript Reference error because 'is not defined' in the context

I've been grappling with this specific error for the last couple of hours, and it's definitely not a run-of-the-mill undefined error. The issue arises when I define a value in the webpack plugins section (for a global variable) to serve as an API ...