Nate
Nate

Reputation: 7866

Pipe update for each control change in reactive form

I'm having troubles using a pipe in my reactive form. I have a pipe that transforms my object into an array so it can be used with *ngFor.

So far so good... the problem is that when I create an input (using form control to bind the value) inside my *ngFor, each change in this input triggers a pipe update. The result is that my input loses focus each time I write one letter in the input.

HTML:

<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm.value, myForm.valid)">
  <div *ngFor="let item of myForm.controls.object.value | keys" formGroupName='object'>
    <label>{{lang}}</label>
      <input name="item" type="text" placeholder="Option" [formControlName]="item.key"/>
  </div>
</form>

And my pipe:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'keys'
})

export class KeysPipe implements PipeTransform {
    transform(value, args:string[]) : any {

        if (!value) {
            return value;
        }

        let keys = [];
        for (let key in value) {
            keys.push({key: key, value: value[key]});
        }
        return keys;
    }
}

Here is a plunker to demonstrate the issue.

How can I make the pipe inactive when I write or can I use a different approach than a pipe?

Please note that I can't change my object and that it has unkown properties (item1 and item2 in the plunker example)

Upvotes: 2

Views: 1864

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657771

This might fix the issue

<div *ngFor="let item of myForm.controls.object.value | keys trackBy:trackByIdx" formGroupName='object'>
trackByIdx(index: number, obj: any): any {
  return index;
}

I think the problem is caused because *ngFor iterates over primitive values that are modified. *ngFor can't match the previous value with the new one and therefore removes the item and adds another one.

See also Angular2 NgFor inside tree model: wrong order when remove and then add elements

Upvotes: 1

Related Questions