typescript - how - rxjs observable example
Encadenamiento de observables RxJS a partir de datos http en Angular2 con TypeScript (1)
Para su caso de uso, creo que el operador
flatMap
es lo que necesita:
this.userData.getUserPhotos(''123456'').flatMap(data => {
this.userPhotos = data;
return this.userData.getUserInfo();
}).subscribe(data => {
this.userInfo = data;
});
De esta manera, ejecutará la segunda solicitud una vez que se reciba la primera.
El operador
flatMap
es particularmente útil cuando desea utilizar el resultado de la solicitud anterior (evento anterior) para ejecutar otra.
No olvide importar el operador para poder usarlo:
import ''rxjs/add/operator/flatMap'';
Esta respuesta podría darle más detalles:
Si solo quieres usar el método de
subscribe
, usa algo como eso:
this.userData.getUserPhotos(''123456'')
.subscribe(
(data) => {
this.userPhotos = data;
this.userData.getUserInfo().subscribe(
(data) => {
this.userInfo = data;
});
});
Para finalizar, si desea ejecutar ambas solicitudes en paralelo y recibir una notificación cuando se
import ''rxjs/add/observable/forkJoin''
todos los resultados, debería considerar usar
Observable.forkJoin
(debe agregar
import ''rxjs/add/observable/forkJoin''
):
Observable.forkJoin([
this.userData.getUserPhotos(),
this.userData.getUserInfo()]).subscribe(t=> {
var firstResult = t[0];
var secondResult = t[1];
});
Actualmente estoy tratando de enseñarme a mí mismo Angular2 y TypeScript después de trabajar felizmente con AngularJS 1. * durante los últimos 4 años. Tengo que admitir que lo estoy odiando, pero estoy seguro de que mi momento eureka está a la vuelta de la esquina ... de todos modos, he escrito un servicio en mi aplicación ficticia que obtendrá datos http de un backend falso que escribí que sirve a JSON.
import {Injectable} from ''angular2/core'';
import {Http, Headers, Response} from ''angular2/http'';
import {Observable} from ''rxjs'';
@Injectable()
export class UserData {
constructor(public http: Http) {
}
getUserStatus(): any {
var headers = new Headers();
headers.append(''Content-Type'', ''application/json'');
return this.http.get(''/restservice/userstatus'', {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError);
}
getUserInfo(): any {
var headers = new Headers();
headers.append(''Content-Type'', ''application/json'');
return this.http.get(''/restservice/profile/info'', {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError);
}
getUserPhotos(myId): any {
var headers = new Headers();
headers.append(''Content-Type'', ''application/json'');
return this.http.get(`restservice/profile/pictures/overview/${ myId }`, {headers: headers})
.map((data: any) => data.json())
.catch(this.handleError);
}
private handleError(error: Response) {
// just logging to the console for now...
console.error(error);
return Observable.throw(error.json().error || ''Server error'');
}
}
Ahora en un Componente deseo ejecutar (o encadenar) los
getUserInfo()
y
getUserPhotos(myId)
.
En AngularJS esto fue fácil ya que en mi controlador haría algo como esto para evitar la "Pirámide del destino" ...
// Good old AngularJS 1.*
UserData.getUserInfo().then(function(resp) {
return UserData.getUserPhotos(resp.UserId);
}).then(function (resp) {
// do more stuff...
});
Ahora he intentado hacer algo similar en mi componente (reemplazando
.then
por
.subscribe
) sin embargo, mi consola de error se está volviendo loca.
@Component({
selector: ''profile'',
template: require(''app/components/profile/profile.html''),
providers: [],
directives: [],
pipes: []
})
export class Profile implements OnInit {
userPhotos: any;
userInfo: any;
// UserData is my service
constructor(private userData: UserData) {
}
ngOnInit() {
// I need to pass my own ID here...
this.userData.getUserPhotos(''123456'') // ToDo: Get this from parent or UserData Service
.subscribe(
(data) => {
this.userPhotos = data;
}
).getUserInfo().subscribe(
(data) => {
this.userInfo = data;
});
}
}
Obviamente estoy haciendo algo mal ... ¿cómo sería mejor con Observables y RxJS? Lo siento si estoy haciendo preguntas estúpidas ... pero gracias por la ayuda de antemano! También he notado el código repetido en mis funciones al declarar mis encabezados http ...