Reputation: 197
I'm building a little website in Angular and i'm facing a wall.
I got the following,
<app-details *ngIf="(selected | async)" [selected]="selected | async"></app-details>
In the parent, selected is an observable.
public selected: Observable<any>;
constructor(private store: Store<State>) { }
ngOnInit() {;
this.selected = this.store.pipe(select(selectSelectedChamp));
}
In my child, I want to do some work on selected
:
@Input() selected: any;
public data: Array<{
preview: string,
thumbnail: string,
alt: string,
}>
constructor() { }
ngOnInit(): void {
this.data= this.selected.map(skin => {
return {
preview: ... ,
thumbnail: ...,
alt: ...
}
})
}
Problem is, selected
doesn't seems to be initalized, if I log it, it's empty, and I got an error on the map... Cannot read property 'map' of undefined
Maybe adding the visual effect will help understanding. I want to be able to visualize image, skins and infos on different League Of legends characters on click.
On the first click, my variable is not initialized, ie. image is not displaying, On the second click tho', image is displaying, but one click late ?
Upvotes: 1
Views: 3885
Reputation: 29325
you probably was to declare the async
result as a template variable like so:
<app-details *ngIf="selected | async as selection" [selected]="selection"></app-details>
this way you're not subscribing multiple times, the initial value from the async pipe will always be undefined, you work around tht this way. next, you probably want to use a setter input:
private _selected;
@Input()
set selected(value: any) {
this._selected = value;
this.data = value.map(skin => {
return {
preview: ... ,
thumbnail: ...,
alt: ...
}
})
}
get selected() {
return this._selected
}
this way, that map routine will run everytime the input value changes.
Upvotes: 0
Reputation: 2199
Try this:
<app-details *ngIf="(selected | async) as selection" [selection]="selection"></app-details>
@Input() selection: any;
public data: Array<{
preview: string,
thumbnail: string,
alt: string,
}>
constructor() { }
ngOnInit(): void {
this.selection.pipe(take(1)).subacribe(res => {
// Your code here...
}
})
}
Upvotes: 0
Reputation: 850
Change this part:
[champDetails]="selected | async"
to this:
[selected]="selected | async"
Explanation: The childs component @Input name is selected
, so in parent you must use [selected]=...
. Otherwise selected
is undefined, hence the error Cannot read property map of undefined
.
Upvotes: 3