1

I am new to angular and i'm having trouble binding data from a data service to FormGroup. I am able to access the properties in the view just fine but the same properties are undefined inside the controller where I try to create the form group and set it's initial form control values.

Model

export class Dog {
  constructor(
    id: number,
    name: string,
    age: number
  ) { }
}

Service

getDog(): Promise<Dog> {
  return this.http.get(this.baseUrl + '/api/endpoint').toPromise().then(res.json()); 
}

Component I then call this service from my component like:

export class DogComponent implements OnInit {
  form: FormGroup;
  dog: Dog;

  constructor(private service: DogService, private fb: FormBuilder) { }

  ngOnInit(): void {
    this.getData();
    this.createForm();
  }

  getData() {
    this.service.getDog().then(res => this.dog = res);
  }

  createForm() {
    this.form = this.fb.group({
      id: [this.dog.id],
      name: [this.dog.name],
      age: [this.dog.age]
    });
  }
}

View

<form [formGroup]="form">
  <input formControlName="name" />
  <input formControlName="age" />
</form>

I am able to set the input value like [value]="name" but I want to be able to set those in the createForm method. Any ideas why the properties are available to the view but not inside the controller

Stanislav Kvitash
  • 4,614
  • 18
  • 29
jordanpowell88
  • 857
  • 3
  • 11
  • 25
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Igor Sep 01 '17 at 17:57
  • Also your service should not compile, look a the `then` statement. – Igor Sep 01 '17 at 17:57

2 Answers2

1

Http calls are asynchronous in nature .So you have to wait for the data before you use that data.So call createForm() method inside getDog().then.I would change your code as follows

export class DogComponent implements OnInit {
form: FormGroup;
dog: Dog;

constructor(private service: DogService, private fb: FormBuilder) {}

ngOnInit(): void {

    this.form = this.fb.group({
        id: [""],
        name: [""],
        age: [""]
    });
    this.getData();

}

getData() {
    this.service.getDog().then(res => {
        this.dog = res;
        this.createForm();
    });
}

createForm() {
    this.form.setValue({
        id: this.dog.id,
        name: this.dog.name,
        age: this.dog.age
    });

}
}

Code isn't tested ...Hope this helps to understand the concept

Vikhyath Maiya
  • 3,122
  • 3
  • 34
  • 68
0

They are null because the promise to get the data has not completed yet. Do this inside your getData:

  getData() {
    this.service.getDog().then(res => {
      this.dog = res;
      this.createForm();
    });
  }
Ben Richards
  • 3,437
  • 1
  • 14
  • 18
  • just a doubt without testing this.Wouldnt this throw an error as createForm is called in the subscribe method ,but view will be initialised before the http call completes hence template wont be able to find any formcontrol with name or id.? – Vikhyath Maiya Sep 01 '17 at 18:09
  • Yup. The code doesn't account for the form creation. – Ben Richards Sep 01 '17 at 18:11