I'm trying, as a personal challenge, to create a website where you can see a list of League Of Legends champions, and click on their icons to get more details.
However, the details of my champions (images specifically), seems to display one click late.
Here, I clicked on the image of Kaisa
, but the image of the previous champ is displaying
Here is how I get my datas.
PARENT TS
export class ChampionListComponent implements OnInit {
public displayPopup = false;
public selectedChamp: Observable<any>;
constructor(private store: Store<LolState>) { }
ngOnInit() {
this.selectedChamp = this.store.pipe(select(selectChampDetails));
}
selectChamp(name) {
this.displayPopup = true;
this.store.dispatch(new GetChampionsDetails(name));
}
PARENT HTML
<ul class="champion_list">
<li (click)="selectChamp(champion.key)">
...List of champions
</li>
</ul>
<ng-container *ngIf="displayPopup">
<app-champion-details *ngIf="selectedChamp | async as champ" [selectedChamp]="champ"></app-champion-details>
</ng-container>
CHILD TS
export class ChampionDetailsComponent implements OnInit {
@Input() selectedChamp: any;
public skins: Array<{path: string}>;
constructor() { }
ngOnInit(): void {
if (this.selectedChamp.skins) {
this.skins = this.selectedChamp.skins.map(skin => {
return {path: 'LINK'}
})
}
}
CHILD HTML
<section *ngIf="selectedChamp as Champ" class="container">
<carousel cellWidth="100%" cellToShow="1" [loop]="true" [images]="skins"></carousel>
<div class="champ_infos">
<h2>{{Champ.id | titlecase}}</h2>
<h3>{{Champ.title | titlecase}}</h3>
<article>
{{Champ.lore}}
</article>
</div>
</section>
I'm getting the infos from my service, which is called by an effect, that dispatch actions, storing data in my state. The infos are well stored in my state, if I try to console.log selectChamp
in the parent, it display the good information, no problem here.
It seems that Angular is trying to perform the map
before the input received the information?
Edit: I replace *ngIf="selectedChamp as Champ"
by *ngIf="skins"
in my child, so the content doesn't show unless it's totally loaded, you can see the result in my gif.
(I removed some code that isn't really relevant for my problem, if there are some typos / unknown variables, please ignore it, as it's not the source of my problem)
When you use inputs for a child component, the value is available in OnChanges life cycle. So you can try this:
ngOnChanges(changes: SimpleChanges) {
if(changes && this.selectedChamp && this.selectedChamp.skins){
this.skins = this.selectedChamp.skins.map(skin => {
return {path: 'LINK'}
})
}
}
in this life cycle every time the value updates in the parent, you can get it in child component.