Thinker
Thinker

Reputation: 5356

angular2 child component does not load on subsequent event fired from parent component

I have a parent component Home and a child component Hall. From Home I select a city and based on selected city I am trying to load all the 'halls' from my Hall component.

Home HTML:

<div class="dropdown">
        <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">Select your city</button>
        <div class="dropdown-content">
            <ul *ngFor = "let city of cities">
                <a (click)="selectCity(city)" > {{city.name}} </a>
            </ul>
        </div>
        <hall *ngIf = "isSelectHall" [city]="specific_city" ></hall>
</div>

Home component:

constructor(private homeService: HomeService) {
}

ngOnInit() {
    this.homeService.getCities().then (
        data => {
            this.cities = data;
        });     


}

selectCity(city:any) {
    this.specific_city = city;
    this.isSelectHall = true;
}

Hall component:

export class Hall implements OnInit{
    @Input() city: any;

    halls: Object;
    openDiv : boolean;
    specific_hall: Object;
    cart : any;
    cartCount: number;
    cartHalls: any;
    countHall: number;

    constructor(private hallService: HallService){

        this.cart=[]; 
    }

    ngOnInit(){
        this.fetchData(this.city.id)
    }

    fetchData(cityId : any) {

        this.hallService.fetchData(cityId)
        .then( 
            data => {
                this.halls = data;
            });
    }

    clicked(item : any) {

        this.specific_hall = item
    }

    onNotify(cartItems : any) : void {

        this.cartHalls = cartItems;
        this.cartCount = this.cartHalls.length;
    }
}

Hall HTML:

<div class="mdl-grid">
    <div class="mdl-cell mdl-cell--4-col">
        <div class="populate-table" [hidden]="!halls">
            <table>
                <tr>
                    <th>Name</th>
                    <th>Landmarks</th>
                    <th>Seating capacity</th>
                    <th>Details</th>
                </tr>
                <tr *ngFor="let item of halls">
                    <td> {{ item.name }} </td>
                    <td> {{ item.landmarks }} </td>
                    <td> {{ item.seating_capacity }} </td>
                    <td> <a (click)="clicked(item)"> See </a> </td>
                </tr>
            </table>
        </div>
    </div>

The problem I am facing is: on first click on selectCity(city) in Home it loads all the halls specific to chosen city, however it does not have any effect when I click on any other city afterwards. What am I doing wrong here?

Scrrenshot:

enter image description here

Upvotes: 1

Views: 382

Answers (2)

deek
deek

Reputation: 1095

You need to set a trigger to re run fetchData method in the child; something like onChanges or communicate with the child component(see below). ngInit will run once but not again everytime a change occurs to a component property. Here's an example of your code with a get/set way of parent/child communication.

Parent/child component interaction: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child

    private this._city: Object;

    @Input ()

    set city(city: Object) {
    this._city = city;
    this.fetchData(this.city.id); 
//whenever city changes via Input, halls is updated which will cause *ngFor to re-render)
    }

    get city() {
    return this._city;
    }

Upvotes: 1

Chris
Chris

Reputation: 1558

Add a setter to your input like described in https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter and trigger a call to fetchData from it. Should look like this (not tested):

export class Hall implements OnInit{
    private _city: any = {};

    @Input() 
    set city(city: any) {
        this._city = city;
        this.fetchData(this.city.id);
    }

Upvotes: 1

Related Questions