Home > Enterprise >  Angular update variable value when form input is changed
Angular update variable value when form input is changed

Time:08-07

I am using Angular and i have a generated model that needs to get the compute the age when the user inserts the age, i am doing it with Reactive forms with the following code (reused the generated component name-editor for testing purpouses): In components.ts:

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-name-editor',
  templateUrl: './name-editor.component.html',
  styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {
  name = new FormControl(new Date());
  age = new Date().getFullYear() - (this.name.value as Date).getFullYear();
  check = (this.name.value as Date).getFullYear();
}

In component.html:

<form>
    <label for="name">Name: </label>
    <input id="name" type="date" [formControl]="name" [ng]>
    <p>Value: {{ name.value }}</p>
    <p>Age: {{ age}}</p>
    <p>{{check}}</p>
</form>

The result is: enter image description here, as you can see the value is changed and detected, but age and check does not change, how i can get the updated value of both elements?

CodePudding user response:

One thing you could do is subscribe to name.valueChanges. First you would start by adding this ngIf to the html:

<form *ngIf="{n:name$|async}">

Then you would just watch for changes on name.valueChanges from the FormControl and apply the updates you would like through tap:

export class AppComponent {
  name = new FormControl(new Date());
  age = this.getAge();
  check = this.getCheck();

  // Watches for changes on name and when a change happens
  // both age and check will be re-calculated
  name$ = this.name.valueChanges.pipe(
    tap(() => this.age = this.getAge()),
    tap(() => this.check = this.getCheck())
  );

  getAge() {
    return new Date().getFullYear() - this.getCheck();
  }

  getCheck() {
    return new Date(this.name.value).getFullYear();
  }
}

This option is good because it only executes when the value on name gets changed, whereas the next option (see below) executes whenever any property changes.


Another option is to use ngDoCheck() which will run a check whenever angular runs it's change hook(s) on a bound property change.

export class AppComponent implements DoCheck {
  // These are bound to the template, so they will cause
  // change detection to run when they get updated
  name = new FormControl(new Date());
  age = this.getAge();
  check = this.getCheck();

  // Runs when bound properties are changed
  ngDoCheck() {
    this.age = this.getAge();
    this.check = this.getCheck();
  }

  getAge() {
    return new Date().getFullYear() - this.getCheck();
  }

  getCheck() {
    return new Date(this.name.value).getFullYear();
  }
}
  • Related