Recabamos por el mundo online para así mostrarte la solución a tu duda, si continúas con alguna duda puedes dejar tu pregunta y contestamos con mucho gusto, porque estamos para ayudarte.
Solución:
Debería leer un poco sobre los operadores de rxjs. Sus ejemplos son muy detallados y usan flatMap
y map
de una manera que se supone que no deben ser utilizados. Además, su primer ejemplo no puede funcionar, porque no se está suscribiendo al Observable.
Esto hará lo que necesitas:
ngOnInit()
this.userService.getUser().pipe(
tap(u => this.user = u),
flatMap(u => this.userService.getPreferences(u.username))
).subscribe(p => this.preferences = p);
legado:
Antes de la versión 5.5, rxjs utilizaba exclusivamente operadores basados en prototipos. Este código es funcionalmente equivalente al anterior:
ngOnInit()
this.userService.getUser()
.do(u => this.user = u) //.do just invokes the function. does not manipulate the stream, return value is ignored.
.flatMap(u => this.userService.getPreferences(u.username))
.subscribe(p => this.preferences = p);
Muy bien, después de un día de lucha y recopilación de información de Internet, esto es lo que aprendí sobre encadenar Observables (Llamar a Observables en una secuencia, uno tras otro):
Estoy trabajando en un sitio web Angular2 (4) y este sitio utiliza una API de back-end de Java para obtener/establecer/modificar la información en la base de datos.
Mi problema fue que tuve que hacer dos llamadas API (HTTP POST) en una secuencia que devuelve Observables (RxJS).
Tengo Operation1 y Operation2. Operación 2 Debe ejecutarse después de completar la operación 1.
Variant1 -> Al principio lo hice uno dentro de otro (como funciones anidadas en javascript):
this.someService.operation1(someParameters).subscribe(
resFromOp1 =>
this.someService.operation2(otherParameters).subscribe(
resFromOp2 =>
// After the two operations are done with success
this.refreshPageMyFunction()
,
errFromOp2 =>
console.log(errFromOp2);
);
,
errFromOp1 =>
console.log(errFromOp1);
);
A pesar de que este código es legítimo y funciona, tenía el requisito de encadenar estos Observables uno tras otro, como se hace con funciones asíncronas con Promises. Una forma es convertir Observables en Promesas.
Otra forma es usar RxJS flatMap:
Variant2 -> Otra forma es hacer esto con flatMap que, según entendí, es similar a Promises entonces:
this.someService.operation1(someParameters)
.flatMap(u => this.someService.operation2(otherParameters))
.subscribe(function()
return this.refreshPageMyFunction()
,
function (error)
console.log(error);
);
Variant3 -> Lo mismo con las funciones de flecha:
this.someService.operation1(someParameters)
.flatMap(() => this.someService.operation2(otherParameters))
.subscribe(() => this.refreshPageMyFunction(),
error => console.log(error)
);
Los métodos que devuelven Observables son básicamente estos:
operation1(someParameters): Observable
return this.http.post('api/foo/bar', someParameters);
operation2(otherParameters): Observable
return this.http.post('api/some/thing', otherParameters);
Recursos adicionales y comentarios útiles:
This post approved answer by @j2L4e: https://stackoverflow.com/a/40803745/2979938
https://stackoverflow.com/a/34523396/2979938
https://stackoverflow.com/a/37777382/2979938
los versión 1 es lo mejor y debería funcionar, solo olvidaste suscribirte a:
ngOnInit()
this.userService.getUser()
.flatMap(u =>
this.user = u; // save the user
return Observable.of(u); // pass on the Observable
)
.flatMap(u => this.userService.getPreferences(this.user.username)) // get the preferences for this user
.map(p =>
this.preferences = p; // save the preferences
)
.subscribe();