15

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.

Sajjad
  • 853
  • 2
  • 15
  • 32
  • your code ts code is correct, are you getting any error in the console? I am assuming, there may be an issue with your JSON data. – Ajay Ojha Nov 02 '18 at 16:42
  • No errors. I have tried hardcoding the values as well. – Sajjad Nov 02 '18 at 16:43
  • I have created a sample app on stackblitz based on your scenario and it is working fine, please check on this link https://stackblitz.com/edit/angular-r7tswz?file=src%2Fapp%2Fapp.component.html and let me know – Ajay Ojha Nov 02 '18 at 16:44
  • 1
    I believe the problem is you are binding html with formcontrol and setting a value in formgroup, that's the reason you are not getting the value in the control. please check stackblitz example html code. – Ajay Ojha Nov 02 '18 at 16:51

2 Answers2

4

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 the 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:

Mathias
  • 1,819
  • 4
  • 22
  • 34
nircraft
  • 8,242
  • 5
  • 30
  • 46
  • The problem is not with the `doc` object since it has nested values there for I have used `doc.name.text` which returns me the required value, it's just they are not being reflected in the form. The same works if I do not use `FormBuilder` approach and specifically intialize FormControls at global level. Even I have tried setting the hardcoded values and they don't work. – Sajjad Nov 02 '18 at 15:25
  • The problem is with the way you are using formControlName: It should be: – nircraft Nov 02 '18 at 16:58
  • @Sajjad, please accept the answer if it works for you. thanks! – nircraft Nov 02 '18 at 17:45
  • Yes, instead of `formControl`, I had to use `formControlName`. – Sajjad Nov 06 '18 at 10:20
1

the problem is that in your html, the input has "formControl", so the correct way to bind formGroup with form in this case is use [formControlName] directive.

change your html for:

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

and everything gonna be alright