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é this
no 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
gotMessages
como una devolución de llamada, cuando se está ejecutando, el alcance es diferente y, por lo tanto,this
no es lo que esperaba.La
bind
función devuelve una nueva función que está vinculada althis
definido por usted.Por supuesto, también puede usar una función de flecha allí:
getMessages() { this.apiService.getMessages(messages => this.gotMessages(messages)); }
Prefiero la
bind
sintaxis, 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 elthis
contexto correcto .Puede solucionarlo fácilmente utilizando una lambda que enlaza automáticamente el
this
contexto 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