I wrote a function that gets and shows the "best player" from my array of objects (the player who has most likes). The function works fine and shows me what I want, but the browser shows me errors in the console, and the routing in my app is blocked (I can't navigate between components using routes)
this is my DashboardComponent Class
export class DashboardComponent implements OnInit {
bestPlayer:Player;
data:Player[]=[];
max:number =0;
constructor(private playerService : PlayerService ,private router: Router) { }
ngOnInit() {
this.playerService.getData().then(data => {
this.data = data;
for (var i = 0; i <= this.data.length; i++) {
if (this.data[i].likes>this.max) {
this.max=this.data[i].likes;
this.bestPlayer=this.data[i];
}
}
});
}
viewDetails(bestPlayer: Player):void {
this.router.navigate(['/detail',this.bestPlayer.id]);
}
}
This is my service:
import {Player} from './player';
import {PlayersData} from './muck-players';
import { Injectable } from '@angular/core';
@Injectable()
export class PlayerService {
players:any;
data:any;
Player:Player;
getData():Promise <Player[]> {
return Promise.resolve(PlayersData);
}
}
when I run the app the browser show me those errors :
TypeError: this.data[i] is undefined Error: Uncaught (in promise): Error: Cannot activate an already activated outlet Error: Uncaught (in promise): Error: Cannot activate an already activated outlet
when I delete whats in ngOninit() and viewDetails() function, routing starts working again and browser doesn't show me errors.
Any help please !
As a sidenote, always when you provide a plunker, make sure it's a working one ;) When I got it working, there was only a couple of issue actually. There was nothing wrong with your routing. The first error you were getting
this.data[i] is undefined
is because of your for loop, you had marked that we should loop until i matches the length of the array (or equal). But we need to remember that the index of arrays start with 0. So the last iteration it was trying to read an index that was not present in your array. So you should add -1 to your for loop:
for (var i = 0; i <= this.data.length-1; i++)
or do
for (var i = 0; i < this.data.length; i++)
When this was fixed, it produces new issues. Since data is coming async, so by the time the template is rendered, your variable bestPlayer is undefined. This can be fixed with safe navigation operator, or wrapping everything inside a div with the condition that bestPlayer has values. This need to be applied to both the detail page and the dashboard. With the dashboard:
<div *ngIf="bestPlayer">
<!-- code here -->
</div>
And in the detail page the same but using player instead, as that is the variable you are using there.
As mentioned, you can also use the safe navigation operator.
These actually cleared the second error you also had.
Here's your fixed PLUNKER.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With