Angular2: TypeError 'this.' undefined

I wrote a function that gets and shows the "best player" from my array of objects (the player who likes the most). The function works fine and shows me what I want, but the browser shows me errors in the console and routing in my application is blocked (I cannot 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 shows me these errors:

TypeError: this.data [i] is undefined Error: not visible (in a promise): Error: do not activate an already activated socket Error: not shown (in a promise): Error: do not activate an already activated socket

when I remove the functions ngOninit()

and viewDetails()

, the routing starts working again and the browser doesn't show me errors.

Any help please!

+3


source to share


3 answers


Assalamualaikum,

I have dozens of bugs fixed in Plunker and added some missing routing features. The app is working fine now, please take a look at my forked Plunker here

I fixed all the file paths and used in the forEach

method in your component like so:



ngOnInit() { 
  this.playerService.getData().then(data => {
      data.forEach( (arrData) => {
      if (arrData.likes>this.max) {
      this.max=arrData.likes;
      this.bestPlayer=arrData;
      }
    }) 
  });
}

      

I really hope this helps you Hamdi and wishes you all the best for your project and if you have any questions just let me know, I will be more than happy to help enter image description here

Ramadan Mubarak.

+1


source


As a side-item, whenever you provide a plunker, make sure it works.) When I got it working, there were really only a couple of problems. There was nothing wrong with your routing. The first error you received

this.data [i] - undefined

due to your for loop, you noted that we must loop until i

it matches the length of the array (or equal). But we must remember that the index of arrays starts with 0

. So the last iteration was trying to read an index not present in your array. Therefore, you must add -1

to the 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 has been fixed, new issues arise. Since the data comes in async, so by the time the template is rendered, your variable bestPlayer

is undefined. This can be eliminated with a safe navigation statement or wrapped with a condition, which matters. This needs to be applied on both the detail page and the dashboard. Using the control panel: div

bestPlayer

<div *ngIf="bestPlayer">
  <!-- code here -->
</div>

      

And on the detail page is the same, but using player

instead, since this is the variable you are using there.

As mentioned, you can also use Safe Navigator.

They did clean up the second error you also had.

Here is your fixed PLUNKER .

+3


source


Hi there is a problem with your service,

You are trying to iterate over data that is not available,

You need to change the code, If you are using Observer as a service then put the code inside the .subscribe method,

If you are using a promise, put your looping code in the .then () method.

Try using this:

If you return a promise from this.playerService.getData()

this service

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];


  }
})

      

If you are returning an observable from this.playerService.getData()

this service

   this.playerService.getData().subscribe((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];
      }
    })

      

+1


source







All Articles