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

What is the process for integrating additional Firebase Cloud Functions into an Angular Universal project?

When working on an Angular Universal project, the fixed configuration for firebase.json looks like this: { "hosting": [{ "target": "PROJECT-ID", "public": "dist/PROJECT-ID/dist/PROJECT-ID/bro ...

What is the best way to access the data stored within a Promise object in a React application?

Below is the snippet of my code that handles parsing application data: async function parseApplication(data: Application) { const fieldGroupValues = {}; for (const group of Object.keys(data.mappedFieldGroupValues)) { const groupValue = data.mappedF ...

Navigating focus within form elements using Angular techniques

Purpose There is a form with various input elements (el1, el2 ...) el1 may or may not have initial focus when a keydown event occurs, the following actions should be taken: If none of the input elements are in focus, move focus to the first non-empty e ...

The const keyword is not automatically inferred as a const when using conditional types for generic type parameters

Within Typescript, the const modifier can be applied to function type parameters. This ensures that the inferred type matches the literal received with as const. function identity<const T>(a: T){ return a } For example, when using identity({ a: 4 ...

Bidirectional binding with complex objects

In my Angular2 app, I have a class called MyClass with the following structure: export class MyClass { name: Object; } The name object is used to load the current language dynamically. Currently, for two-way binding, I am initializing it like this: it ...

Leverage async-await in conjunction with subscription

I am struggling with a tangled mess of code known as 'callback hell'. Can someone please guide me on how to make use of async-await to simplify the debugging process and tidy up this situation? this.ws.call('vm.image_path', ['Ran ...

Embracing Angular2 - incorporating external modules

Attempting to incorporate the phoenix_js NPM module into my Angular2 app (which was created using the Angular2 CLI) is proving to be a challenge. I keep encountering the error message Cannot find module 'phoenix_js'. Many others have also faced t ...

What is the best way to show the previous month along with the year?

I need help with manipulating a date in my code. I have stored the date Nov. 1, 2020 in the variable fiscalYearStart and want to output Oct. 2020. However, when I wrote a function to achieve this, I encountered an error message: ERROR TypeError: fiscalYear ...

Using AngularJS2, store the AJAX data in a class variable

I'm currently working on this code and I'm struggling to understand why the data retrieved through AJAX isn't being assigned to the class variable this.users. Snippet of Code getUsers() { this.http.get('/app/actions.php?method=us ...

How to Utilize Output() and EventEmitter() for Value Transmission in Angular Application

Last week I was successfully able to implement Output() and EventEmitter() in my Angular app. However, today I am facing a new challenge while trying to apply the same concept in a different scenario. I'm not sure what I might be overlooking. Firstly ...

Using event.target to pass HTML form data to FormData is causing an error stating that the Argument of type 'EventTarget' cannot be assigned to a parameter of type 'HTMLFormElement'

Looking to extract data from a form and store it in FormData: const handleSubmit = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); const value = formData.get(' ...

Angular - Automatically populate nested form with provided data

Here is the link to my StackBlitz project: https://stackblitz.com/edit/create-eez7wi?file=app/app.component.ts I am facing an issue where when I load the resources, it fills all fields except for the skill if more than 1 is entered. setResourceDTOS() { ...

Retrieve TypeScript object after successful login with Firebase

I'm struggling with the code snippet below: login = (email: string, senha: string): { nome: string, genero: string, foto: string;} => { this.fireAuth.signInWithEmailAndPassword(email, senha).then(res => { firebase.database().ref(&ap ...

Using command line arguments in a Tauri project with a Next.js frontend

I am utilizing Tauri.JS in conjunction with Next.js. In this scenario, I need to execute the console command: npm run tauri dev --<argument name>=<some value>. Afterwards, I should be able to access the value of the argument in my JavaScript ...

Mastering the art of constraining TypeScript function parameters using interface properties

Hey there, I've been exploring ways to restrict a function parameter so that it only accepts "strings" related to interface properties, similar to what I achieved in the validate fields function: Please note: The TypeScript code provided here is simp ...

What is the best way to click on a particular button without activating every button on the page?

Struggling to create buttons labeled Add and Remove, as all the other buttons get triggered when I click on one. Here's the code snippet in question: function MyFruits() { const fruitsArray = [ 'banana', 'banana', & ...

Sending information to ng-template in Angular6

I'm new to Angular 6 and I have a query. How can I pass data to an ng-template from ngFor? component.html <tr *ngFor="let user of data"> <td>{{user.id}}</td> <td>{{user.username}}</td> <td>{{user ...

adjusting the scrollbar to be positioned at the top when using Material UI stepper component

While using the material ui stepper, I encountered an issue where the scroll bar remains static and hidden behind the step number header when I click on the "save and continue" button. I expect that upon clicking the button, the scroll bar should automatic ...

Typescript validation for redundant property checks

Why am I encountering an error under the 'name' interface with an excess property when using an object literal? There is no error in the case of a class, why is this happening? export interface Analyzer { run(matches: MatchData[]): string; } ...

Exploring the similarities between using jQuery AJAX post and Angular

In my current project, I have a legacy application that relies on jQuery and unfortunately cannot incorporate Angular at this time. For one specific task, I need to make an AJAX POST request to consume a web service using jQuery. Interestingly, the same ...