maidi
maidi

Reputation: 3469

@Input variable gets filled on HTTP request

In my app.component.ts I call a function from a service that returns the result of a HTTP request:

questions: QuestionBase<any>[];
constructor(service: QuestionService) {
    this.questions = service.getQuestions().subscribe(val => console.log(val)); //gets logged after the other console log below
}

In the child component this questions array is processed further:

@Input() questions: QuestionBase<any>[] = [];
form: FormGroup;

constructor(private qcs: QuestionControlService) {}

ngOnInit() {
    console.log("onInit", this.questions); //called before questions is filled
    this.form = this.qcs.toFormGroup(this.questions);
}

My problem is now that the toFormGroup Function in ngOnInit is called too early when the HTTP request hasn't finished. I'm not used to Observables. How could I call the function after the HTTP request in getQuestions has finished. I already tried ngOnChanges but it gets called even before ngOnInit.

Upvotes: 1

Views: 178

Answers (3)

Yakov Fain
Yakov Fain

Reputation: 12376

First of all, you need to assign the value to questions inside the subscribe() call:

service.getQuestions().subscribe(val => this.questions=val);

Also, in the child component, you can implement ngOnChanges() and skip the very first binding to the @Input() property when the value is still null.The SimpleChange class has a boolean property firstChange.

  ngOnChanges(changes: {[key: string]: SimpleChange}) {
    if (!changes.questions.firstChange){
         this.form = this.qcs.toFormGroup(this.questions);}

  }

Upvotes: 3

AVJT82
AVJT82

Reputation: 73367

You could set a condition by checking in the ngOnChanges if questions have values before doing anything with them:

ngOnChanges() {
  if(questions && questions.length) {
     this.form = this.qcs.toFormGroup(this.questions);
  }
}

Upvotes: 1

gonzofish
gonzofish

Reputation: 1417

You can call toFormGroup in an ngOnChanges. And, if you need to, only call toFormGroup when questions gets its first value. I'm on mobile right now so I cannot provide a code sample.

Upvotes: 0

Related Questions