2017-10-11 8 views
1

私は観測オブジェクトを登録すると、支払オブジェクトの配列を返すサービスからオブザーバブルを持っています。ループを実行して各オブジェクトの金額を配列。最初のロードでループが実行されていないという問題は、データがまだ到着していないためです。ただし、オブザーバブルの件名を.nextトリガすれば問題ありません。Angular forEachループオブザーバブルから返されたデータ(Firebase駆動)

そうように私のコンポーネントの機能は次のとおりです。

paymentsSource = new Subject; 
payments$ = this.paymentsSource.asObservable(); 
paymetsData:Payment[] = new Array(); 
totalPaymentsAmoutn:number = 0; 

ngOnInit() { 
    this.payments$ 
    .subscribe(
    (dates:{startDate:number, endDate:number}) => { 
    //Here I need to performe some UTC and Locale conversion to dates thet are being passed on   
     }; 
     //Here I subscribe to my service   
     this.paymentService.getPaymentsByDateRange(dates.startDate, dates.endDate) 
     .subscribe(
     payments => { 
      this.totalPaymentsAmoutn = 0; 
      this.paymetsData = payments; 
      this.paymetsData.forEach(payment => { 
      this.totalPaymentsAmoutn += payment.amount; 
      }) 
      });  
     }); 


//this.paymentsStartDate is declear some where else but it does exist previous to this point 
this.paymentsSource.next({startDate:this.paymentsStartDate, endDate:this.paymentsStartDate}); 

} 

//This function I can triger manualy on the view 
onPaymentDateRangeChanged($event){ 
    this.paymentsSource.next({startDate:$event.startDate, endDate:$event.endDate}); 
} 

私のサービス機能は、次のようになります。私は、ページのロードが戻って配列を取得し、ビューが読み込まれます場合は

getPaymentsByDateRange(startDate:number, endDate:number):Observable<Payment[]>{ 
    let paymentsArray:Payment[] = []; 
    this.af.list('/bookings') 
     .subscribe(
     (bookings) => { 
      for(let booking of bookings){ 
      if(booking.payments){ 
       for(let payment of booking.payments){ 
       //condition for date range 
       if(startDate <= payment.date && payment.date <= endDate){ 
        payment.booking_key = booking.$key; 
        paymentsArray.push(payment); 
       } 
       } 
      } 
      } 
      //Sorting payments cronologicaly 
      paymentsArray.sort(function(paymentA, paymentB){ 
      return paymentA.date - paymentB.date 
      }); 
     } 
    ); 
    return Observable.of(paymentsArray); 
    } 

が、 this.totalPaymentsAmoutnの値は0のままです。関数を手動でトリガーすると、配列が返されthis.totalPaymentsAmoutnが完全に更新されます。

私はObservablesで少し新しく、新しいデータが放出されると購読すると思っていました。スクリプトを実行してデータを更新する必要があります。なぜ最初の読み込みがうまくいかないのか分かりません。配列がまだ空であり、ウェブソケットが接続されると、結果的に更新が十分に速くなると思うので、forEachループを実行できないと思うのですか?

答えて

0

getPaymentsByDateRange()メソッドに切断があります。 paymentsArrayが移入される前に返されます。

getPaymentsByDateRange(startDate: number, endDate: number): Observable<Payment[]>{ 
    let paymentsArray: Payment[] = []; 
    this.af.list('/bookings') 
     .subscribe(...); // asynchronous 
    // since this.af.list.subscribe is asynchronous, this returns before that call is finished. 
    return Observable.of(paymentsArray); 
} 

代わりaf.list、観察を返すと成分のみに加入しなければなりません。コンポーネントがそれを使用する前に、前処理にデータが必要な場合は、これは、あなたがこの方法をサブスクライブするとき、onNextコールバックのみaf.list観測可能発したら発火することが保証さrxjs .MAPオペレータ

import 'rxjs/add/operator/map'; // import map operator 

getPaymentsByDateRange(startDate: number, endDate: number): Observable<Payment[]>{ 
    let paymentsArray: Payment[] = []; // you may want to move this inside the map. If you don't you may get duplicates everytime firebase emits the bookings 
    return this.af.list('/bookings') 
     .map(bookings => { 
      for(let booking of bookings){ 
       if(booking.payments){ 
        for(let payment of booking.payments){ 
         //condition for date range 
         if(startDate <= payment.date && payment.date <= endDate){ 
          payment.booking_key = booking.$key; 
          paymentsArray.push(payment); 
         } 
        } 
       } 
      } 
      //Sorting payments cronologicaly 
      paymentsArray.sort(function(paymentA, paymentB){ 
       return paymentA.date - paymentB.date 
      }); 
      return paymentsArray; 
     }); 
} 

使用することができます。

this.paymentService.getPaymentsByDateRange(dates.startDate, dates.endDate) 
    .subscribe(payments => { 
     // fires when af.list observable emits 
    }); 
+0

本当にありがとうございましたもう少し小さなことですが、私はまだ.mapの後にforループを実行してfirebaseによって返されたリストの各項目を繰り返し処理する必要があります。 'for(予約予約){....' – Xazzo

+0

@Xazzo良いキャッチ、私はそれを私の答えに追加するのを忘れました。更新しました – LLai

関連する問題