Le composant "this" de Angular2 est indéfini lors de l'exécution de la fonction de rappel

J'ai un composant qui appelle un service pour récupérer des données à partir d'un point final REST. Ce service doit recevoir une fonction de rappel pour l'exécution après avoir récupéré ces données.

Le problème est quand j'essaie d'utiliser la fonction de rappel pour ajouter les données aux données existantes dans la variable d'un composant, j'obtiens une EXCEPTION: TypeError: Cannot read property 'messages' of undefined . Pourquoi est- this indéfini?

Version TypeScript: version 1.8.10

Code de contrôleur:

 import {Component} from '@angular/core' import {ApiService} from '...' @Component({ ... }) export class MainComponent { private messages: Array<any>; constructor(private apiService: ApiService){} getMessages(){ this.apiService.getMessages(gotMessages); } gotMessages(messagesFromApi){ messagesFromApi.forEach((m) => { this.messages.push(m) // EXCEPTION: TypeError: Cannot read property 'messages' of undefined }) } } 

Utilisez la fonction Function.prototype.bind :

 getMessages() { this.apiService.getMessages(this.gotMessages.bind(this)); } 

Ce qui se passe ici, c'est que vous transmettez les informations gotMessages tant que rappel, lorsque cela est en cours d'exécution, la portée est différente et donc this n'est pas ce que vous attendiez.
La fonction bind renvoie une nouvelle fonction qui est liée à this vous avez définie.

Vous pouvez bien sûr utiliser une fonction de flèche en gras aussi:

 getMessages() { this.apiService.getMessages(messages => this.gotMessages(messages)); } 

Je préfère la syntaxe de bind , mais c'est à vous de décider.

Une troisième option pour lier la méthode pour commencer:

 export class MainComponent { getMessages = () => { ... } } 

Parce que vous passez simplement la référence de la fonction dans getMessages vous n'avez pas le droit sur this contexte.

Vous pouvez facilement réparer cela en utilisant un lambda qui lie automatiquement le droit à this contexte pour l'utilisation à l'intérieur de cette fonction anonyme:

 getMessages(){ this.apiService.getMessages((data) => this.gotMessages(data)); } 

Ou vous pouvez le faire comme ça

 gotMessages(messagesFromApi){ let that = this // somebody uses self messagesFromApi.forEach((m) => { that.messages.push(m) // or self.messages.push(m) - if you used self }) } 

Définissez la fonction

 gotMessages = (messagesFromApi) => { messagesFromApi.forEach((m) => { this.messages.push(m) }) }