2017-02-12 3 views
1

Wenn ein Observable läuft, hängt es von Daten ab, die von einem anderen Observeravble kommen, und ich kann nicht herausfinden, wie diese Abhängigkeit richtig gehandhabt wird.Umgang mit Observablen, wenn man auf Daten von einem anderen angewiesen ist

Eine beobachtbare erhält Daten von Firebase und abonnieren Sie eine einfache Zahl Array erstellt novelsRead genannt: Array

Die anderen beobachtbaren erhält eine Antwort von einem api und abonnieren Sie es gemeint ist, alle Datensätze herausgefiltert werden, die IDS sind in Romanen vorhanden Read [].

Das Problem ist, wenn eine Antwort von der API kommt, RomaneRead [] ist immer noch leer, weil Firebase noch nicht geantwortet hat, so dass nichts aus der API-Antwort gefiltert wird.

-Code unten:

Exportklasse HomePage {

currentnovels: any; 
novels: any; 
unreadnovels: any; 
nextnovels: any; 
novel: any; 
resultsPageNumber: number = 1; 
novelFullPosterPath: any; 
novelsread: Array<number> = []; 

private basePosterUrlMedium = 'http://image.novels.org/t/p/w500'; 
private basePosterUrlSmall = 'http://image.novels.org/t/p/w185'; 

constructor(private http: Http, 
    private novelsApi: NovelsApiService, 
    private dataService: DataService, 
) { 
    //this takes data from Firebase and pushes it to simple array of ids (numbers) 
    this.dataService.list('novels-read') 
     .subscribe(data => { 
      data.map(results => { 
       this.novelsread.push(results.novelsId); 
      }) 
     }) 
} 


ngAfterViewInit() { 
    this.novelsApi.getnovelsByPage(this.resultsPageNumber) 
    .subscribe(data => { 
     this.novels = data.results; 
     this.novels.map(data => { 

      data.full_poster_path = this.basePosterUrlMedium + data.poster_path; 
      return data; 
     }) 
      .filter(data => { 
       let found = this.novelsread.indexOf(data.id); 
       //It seems when the api responds, this.novelsRead is still empty [] because Firebase has not responded yet 
       console.log("this novelsread[0] is ", this.novelsread[0]); 
       console.log("data.id found is ", found); 
       return data; 
      }) 
    }) 
} 

Ich bin für die sauberste Lösung, ob die Verwendung von Ereignissen sind, oder beobachtbaren Ketten oder andere Vorschläge wie Funktionen aus dem Konstruktor ngAfterViewInit bewegt und und umgekehrt.

Ich habe Codebeispiele zum Kombinieren von Observablen mit combineLatest betrachtet, aber die Syntax war sehr verworren und fragte mich, ob es eine sauberere Art gibt, was ich brauche, selbst wenn das Warten auf Ereignisse beinhaltet.

Antwort

2

Verwenden Sie forkJoin sollte Ihnen helfen. Es erlaubt nur zu behandeln führen, wenn beide Anträge vollständig: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md

oder wenn Ihre zweite Anfrage erste Antwort ist abhängig von - switchMap

const request1$ = Rx.Observable.of('response1').delay(2000); 
 
const request2$ = Rx.Observable.of('response2').delay(100); 
 

 
Rx.Observable.forkJoin(request1$, request2$) 
 
    .subscribe(res => console.log(`forkJoin: ${res}`)); 
 

 
request1$.switchMap(res1 => { 
 
    console.log(`switchMap: ${res1}`); 
 
    return request2$; 
 
}).subscribe(res2 => console.log(`switchMap: ${res2}`));
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

+0

Dank verwenden. Genau das, was ich brauchte. –

Verwandte Themen