Tengo un componente que llama a un servicio para obtener datos de un punto final RESTful. Este servicio debe recibir una función de devolución de llamada para que se ejecute después de obtener dichos datos.
El problema es que cuando intento usar la función de devolución de llamada para agregar los datos a los datos existentes en la variable de un componente, obtengo un EXCEPTION: TypeError: Cannot read property 'messages' of undefined. ¿Por qué thisno está definido?
Versión de TypeScript: Versión 1.8.10
Código del controlador:
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
})
}
}
javascript
arrays
typescript
angular
Michael Gradek
fuente
fuente

tsc -v)Respuestas:
Utilice la función Function.prototype.bind :
getMessages() { this.apiService.getMessages(this.gotMessages.bind(this)); }Lo que sucede aquí es que pasa
gotMessagescomo una devolución de llamada, cuando se está ejecutando, el alcance es diferente y, por lo tanto,thisno es lo que esperaba.La
bindfunción devuelve una nueva función que está vinculada althisdefinido por usted.Por supuesto, también puede usar una función de flecha allí:
getMessages() { this.apiService.getMessages(messages => this.gotMessages(messages)); }Prefiero la
bindsintaxis, pero tú decides.Una tercera opción para vincular el método para comenzar:
export class MainComponent { getMessages = () => { ... } }O
export class MainComponent { ... constructor(private apiService: ApiService) { this.getMessages = this.getMessages.bind(this); } getMessages(){ this.apiService.getMessages(gotMessages); } }fuente
O puedes hacerlo así
gotMessages(messagesFromApi){ let that = this // somebody uses self messagesFromApi.forEach((m) => { that.messages.push(m) // or self.messages.push(m) - if you used self }) }fuente
Debido a que solo está pasando la referencia de la función
getMessages, no tiene elthiscontexto correcto .Puede solucionarlo fácilmente utilizando una lambda que enlaza automáticamente el
thiscontexto correcto para el uso dentro de esa función anónima:getMessages(){ this.apiService.getMessages((data) => this.gotMessages(data)); }fuente
Tengo el mismo problema, resuelto usando () => {} en lugar de function ()
fuente
Defina la función
gotMessages = (messagesFromApi) => { messagesFromApi.forEach((m) => { this.messages.push(m) }) }fuente