how do i trigger the event for a select change from my ts file while working with reactive forms in angular 12

199 views Asked by At

i have a reactive form where i am trying the bind the option of the form from the ts file, i have an selectchange event listener on my mat-select which is triggering when i change or select an option in the Ui , but when i try to bind an option to the mat-select the selectchange event is not triggered , can anyone help me how do i trigger that

well tried this.form.get(formcontrolname).setvalue but which is not triggering the selectchnage event.

My mat-select element-----

  <mat-select [formControlName]="this.getPropertyKey(property)" 
                        (selectionChange)="selectChangeDetected($event, property)" [id]="getIdProperty(property)">

setting form option value from ts file as ----

this.form.get(aliasName)?.setValue(formattedValue);

function triggered when matselect change event is triggered

selectChangeDetected(event: MatSelectChange, property: { [key: string]: string }): void {
// my data manipulations
  }
1

There are 1 answers

2
Eliseo On

(selectionChange) only take account when you change the select using click or by keyboard. It's like if you use the event (input) or (keydown)

You need subscribe to valueChanges

ngOnInit()
{
   const aliasName=???
   this.form.get(aliasName).valueChanges.subscribe((res:any)=>{
       console.log(res)
   })
}

You can also subscribe to any change in your form

   this.form.valueChanges.subscribe((res:any)=>{
       console.log(res) //<--will be the value of your form
   })

Subscribing to form.valueChanges, you can check what "property" change using

this.form.valueChanges
  .pipe(
    startWith(this.form.value),
    pairwise(),
    map(([old, actual]: [any, any]) => {
      return Object.keys(old)
        .map((x) => ({ property: x, value: actual[x], old: old[x] }))
        .filter((x: any) => x.value != x.old)[0];
    })
  )
  .subscribe((res) => {
    console.log(res);
  });

Or (if you don't want the old value)

this.form.valueChanges
  .pipe(
    startWith(this.form.value),
    pairwise(),
    map(([old, actual]: [any, any]) => {
      return Object.keys(old).reduce((a: any, b: string) => {
        return (
          a ||
          (actual[b] == old[b] ? null : { property: b, value: actual[b] })
        );
      }, null);
    })
  )
  .subscribe((res) => {
    console.log(res);
  });

Update if only want to "listen" some changes, we can use some like

  ngOnInit() {
    const controls = ['food', 'fruit'];

    merge(
      ...controls.map((x: string) =>
        (this.form.get(x)?.valueChanges || EMPTY).pipe(
          map((data: any) => ({ property: x, value: data }))
        )
      )
    ).subscribe((res: any) => {
      console.log(res);
    });
  }

See stackblitz