I'm working on an angular firebase app and I don't know how to solve a problem. My @Input is always undefined on my ngOnInit() but I have to init something with this Input value.
ERROR TypeError: Cannot read property 'length' of undefined
I tried to add *ngIf as I saw in similar posts or to initialize my room but nothing is working. Do I have to use a timeout or is there a better way to do that ?
Here are the details:
players component:
@Input() room: Room;
players: Player[];
playersSubscription: Subscription;
constructor(private playerService: PlayerService, private router: Router) { }
ngOnInit() {
this.playersSubscription = this.playerService.playersSubject.subscribe(
(players: Player[]) => {
this.players = players;
}
);
this.playerService.getPlayersRoom(this.room.players);
this.playerService.emitPlayers();
}
html:
<div *ngIf="room">
<ul>
<li *ngFor="let p of room.players">{{p}}</li>
</ul>
</div>
usernames:
<div *ngIf="players">
<ul>
<li *ngFor="let player of players">
{{player.username}} // This will not works
</li>
</ul>
</div>
service:
getPlayersRoom(ids: string[]) {
while (ids.length > 0) {
var id = ids.splice(0, 1)[0];
firebase.database().ref('/users/').child(id).once('value', function (snapshot) {
this.players.push(snapshot.val());
});
}
this.emitPlayers();
}
room:
room: Room;
constructor(private router: Router,
private route: ActivatedRoute,
private roomService: RoomService
) { }
ngOnInit(): void {
this.room = new Room();
const id = this.route.snapshot.params['id'];
this.roomService.getRoom(+id).then(
(room: Room) => {
this.room = room;
}
);
}
html:
<div *ngIf="room">
Room n°{{room.id}} + password {{room.password}}
<h1>PLAYERS room</h1>
<div *ngFor="let p of room.players">
{{p}}
</div>
Players:
<app-players *ngIf="room" [room]="room"></app-players>
end
</div>
Edit: The problem is in ngOnInit (players component): the @Input is undefined at this moment (and then it's doing getPlayersRoom(undefined) ). Any idea someone ? Impossible to use a @Input in constructor/ngoninit ? How should I do that then ?
Room
constructor instantiate theplayers
property to an empty array? I'm asking, because the only location in your code where you uselength
is on theroom.players
array. – David Walschotsthis.room.players
is the problem. Not only you need to make sureroom
is populated, but alsoroom.players
. YourngIf
needs to apply to that, ex.*ngIf="room?.players"
– windmaomaonew Room()
to make sureroom.players
is an empty array upon init. I believe this might make your display layer robust. And you might be able to drop quite a bit*ngIf
– windmaomao