[Fixed] Reactive form fields are not updated with setValue or patchValue

Issue

Following is my piece of code, I have simplified the code for purpose of brevity.

ngOnInit() {
    //intialize form fields 
    this.form = this.builder.group({
      name: '',
      age: '',
      location: '',
    });

    //Call to the service

    this.dataService.getDetails().subscribe(
      (data) => {
        this.dataArray = data;
        if (this.dataArray[this.count].status === 'OK') {
          let docs = {};
          this.someService.getDocs(this.dataArray[this.count].id).subscribe(
            (data) => {
              docs = data;
              console.log("docs: ", docs);
              this.setFormValues(docs);//set form values
            },
            (err) => {
              console.log(err);
              console.log('Something happened');
            }
          );
        }
      },
      (err) => {
        console.log(err);
        console.log('Something happened',err);
      }
    );
  }

Now in setFormValues() I have printed the values of the fields and its working fine up to that point but next when I try to bind the values to the form , with either setValue or patchValue, it simply does not update the form with the fetched values from service.

Some more code in this regard

public setFormValues(doc: DocsDTO) {
    if (doc!= null) {
      console.log("setFormValues", doc);
      this.form.patchValue({
        name: doc.name == null ? '' : doc.name.text,
        age: doc.age == null ? '' : doc.age.text,
        location: doc.location == null ? '' : doc.location.text,
      })
    }
  }

Here is how my form looks like

<form [formGroup]="form">
          <mat-card-content>
            <input placeholder="name" [formControl]="name" id="name"
              ngDefaultControl></input>
            <input placeholder="age" [formControl]="age" id="age" ngDefaultControl></input>
          </mat-card-content>
        </mat-card>
</form>

Note: When I do not use FormBuilder and intialize form fields with FormControl and set form values with this.name.setValue() then it works fine.

I am pretty new to angular , I am not sure what am I doing wrong here.

Solution

This looks fine to me except the place where you are setting up the pathvalue:

The doc.name.text doesn;t look right to me. You should try

this.form.patchValue({
    name: !!doc.name ? doc.name : '',
    age: !!doc.age ? doc.age: '',
    location: !!doc.location ? doc.location : '',
  })

This will update our FormControl instances, simple! Also I think we do not need teh conditional setting here as :

set pathvalue throws no errors due to the if check inside the
Object.keys loop. Some might say it’s a safe $apply, just kidding.
It’ll allow you to set values that exist and it will ignore ones that
do not exist in the current iterated control

On the other hand setValue is a “more safe” way to do things. It’ll error for props that do not exist.

If you add the formControlName properly, it would work:

 <input placeholder="name" formControlName="name" id="name"
          ngDefaultControl>
        <input placeholder="age" formControlName="age" id="age" ngDefaultControl>

take a look at the stackBlitz that i did for you here:

Leave a Reply

(*) Required, Your email will not be published