Ivar Reukers
Ivar Reukers

Reputation: 7719

Angular 2 - @Input - Await async method

Plunkr below

I'm having a problem with Angular's @Input and inputs : [''].

The problem is that I have a person object. This object contains the id (person.id). Now I need to initialize this in the constructor of the 'parent' page: (note: simplified for plunkr, not actual code but same problem).

import { Component } from '@angular/core';
import { Child } from './child.ts';

@Component({
  template: `
    <p>current id: {{person.id}}</p>
    <child-component [input_id]="person.id"></child-component>
  `,
  directives: [Child]
})
export class Parent {
  public person: any;

  constructor() {
    //not neccessary here but it is for production
        this.person = {id: -5, name: ''} 

        this.setPerson()
    }

    setPerson(){
      //just to fake a async method (production will be http.get)

      setTimeout(() => {
        this.person = {id: 3, name: 'test'}
      }, 500);
    }
}

Where I try to send the person.id to the child-component which looks like this:

import { NavController } from 'ionic-angular/index';
import { Component, OnInit , Input} from "@angular/core";


@Component({
  selector: 'child-component',
  template: `
    <div>child:
      <p>Passed id: {{passed_id}}</p>
      <p>Some var: {{someVar}}</p>
    </div>
    `,
    inputs: ['passed_id']
})
export class Child implements OnInit {
  @Input passed_id: number;
  public someVar: number;

  constructor(private nav: NavController) {

    }

    ngOnInit(){
      //cant make into ngAfterViewChecked
      //because that executes too much and the call here
      //will be a heavy http call
      this.someVar = this.passed_id;
    }
}

The problem here is: at first the binding will happen immediately, setting the passed_id to -5. This also sets someVar to -5.

I want to wait untill the passed_id is changed to 3 (by the Parent.setPerson()) and then make a heavy async (http) call.

Now I know I could use angular's ngAfterViewChecked but this executes a lot since I'm working with different kind of 'tabs' and if possible I'd like a spinner to show in the time that passed_id is -5 till its 3. NgAfterViewChecked would execute this many times, showing the spinner many times.

Just wondering if theres a different way to fix this then a if(!check){while(true){ if(this.passed_id != -5){ this.http.get('..')...; break; }}}

http://plnkr.co/edit/nJY29LMzUy0MjlDg2mjv?p=preview

Upvotes: 2

Views: 4227

Answers (1)

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

Reputation: 657741

You can use ngOnChanges() instead of ngOnInit()

ngOnChanges(changes) {
  if(this.passed_id != -5) {
    this.http.get(...)
  }
}

You can also make passed_id a setter

_passed_id:number;
@Input set passed_id(value:number) {
  this._passed_id = value;
  if(this.passed_id != -5) {
    this.http.get(...)
  } 
}

Upvotes: 5

Related Questions