Reputation: 5356
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:
Upvotes: 1
Views: 382
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
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