Angular 2-Devuelve datos directamente desde un Observable
He estado golpeando mi cabeza contra este tratando de averiguarlo, y ninguna cantidad de documentación que he podido leer me ha dado una respuesta a mi pregunta.
Tengo un servicio que está hablando directamente a una API y devolviendo un evento observable al que, en circunstancias normales, me suscribiría y haría lo que quisiera con los datos, sin embargo, en un servicio secundario que utiliza las solicitudes del servicio restful, necesito poder devolver valores del servicio restful. solicitud.
getSomething() {
return this._restService.addRequest('object', 'method').run()
.subscribe(
res => {
res;
},
err => {
console.error(err);
}
);
}
returnSomething() {
return this.getSomething();
}
En el ejemplo rápido anterior, quiero saber si hay alguna forma en que pueda devolver res
desde getSomething()
dentro de returnSomething()
. Si no es alcanzable de esta manera, ¿cuál es la alternativa? Agregaré que el _restService es bastante confiable y realmente no quiero comenzar a jugar con eso.
3 answers
Dado que las llamadas http y similares son asincrónicas, se obtiene un Observable
en lugar de un valor síncrono devuelto. Tienes que suscribirte a él, y en la devolución de llamada de allí obtienes los datos. No hay forma de evitarlo.
Una opción sería colocar su lógica en la llamada subscribe
getSomething() {
return this._restService.addRequest('object', 'method').run()
.subscribe(
res => {
// do something here
res;
},
err => {
console.error(err);
}
);
}
Pero la forma en que me gusta hacerlo es agregar una devolución de llamada, inyectar la lógica desde fuera (tal vez un componente, tal vez otro servicio):
getSomething(callback: (data) => void) {
return this._restService.addRequest('object', 'method').run()
.subscribe(
res => {
callback(res);
},
err => {
console.error(err);
}
);
}
Y en su componente o donde sea:
this._yourService.getSomething((data) => {
// do something here
console.log(data);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-16 19:05:22
Yo no usé esto, pero creo que debería funcionar en teoría (:
// service.ts
getSomething() {
let subject: Subject = new Subject();
this._restService.addRequest('object', 'method').run()
.subscribe(subject);
return subject;
}
// this can be removed (;
returnSomething() {
return this.getSomething();
}
// component.ts
ngOnInit() {
this.service.returnSomething()
.subscribe(res => console.log(res), err => console.log(err));
}
Revisa subject docs para más información. Puede usar diferentes tipos de sujeto, por ejemplo BehaviorSubject tiene value
propiedad a la que puede acceder...
ngOnInit() {
// if you use BehaviorSubject
this.service.returnSomething().value
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-16 19:50:28
Tuve un problema similar. Mi solución fue convertir lo observable en una promesa con .toPromise() (y use async - await para devolverlo y detectar errores). Puedes convertir tu código en algo como:
async getSomething() {
try{
return await this._restService.addRequest('object', 'method').run().toPromise()
} catch (err){
console.error(err);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-05 08:06:59