简体   繁体   中英

RxJs Combine Observables

I'm trying to solve problem when i have two Observables which I want to combine into single value in Angular2 and Angularfire2

lets imagine I have bank account and transactions of two types, outgoing and incoming (its just use case i created for purpose of practice). And I want to sum them together to get actual account balance.

Template:

....
 <div *ngFor="let account of accounts | async">
    {{ (transactionService.getAccountBalance(account) | async )?.balance }}
 </div
 ....

and finally the service which should provide the data

    getAccountBalance(account){
    return Observable.zip(
        this.getIncomingTransactionsForAccount(account), // FirebaseListObservable
        this.getOutcomingTransactionsForAccount(account) // FirebaseListObservable
    , (incoming, outcoming) => {
            ....
            let result = {
                account: account.$key,
                balance: someCalculatedNumber
            };
            console.log(result); // result is correct there
            return result;
        }
    )

}

This one causes infinite loop on Firebase (and doesn't display data in template). I also tried Observer.merge() and some others but I think I'm just trying to use absolutely wrong approach.

Appreciate any help, thanks!

Edit :

just tried another solution, use just one stream to count all incoming transactions:

public getAllIncoming(account: IAccount){

    return this.getIncomingTransactionsForAccount(account)
        .scan((x, y) => {
            console.log(x, y);
            return 1;
        }, 0);
}

generates infinite queries again.

Edit2 :

i tried also forkJoin

    public getAccount2Balance(account: IAccount) {

    return Observable.forkJoin([
            this.getIncomingTransactionsForAccount(account),
            this.getOutcomingTransactionsForAccount(account)
        ], (incoming, outcoming) => {
            ...
            let result = {
                account: account.$key,
                balance: someCalculatedNumber
            };
            console.log(result);
            return result;
        })
}

with same template as above. result: value is not displayed in template and console.log with result is NOT printed

Another option is to try combineLastest . Below is assuming your incoming and outgoing account calls are returning a FirebaseListObservable and you are trying to combine them into one list ( accounts ).

return Observable.combineLatest(

  // added .do() to make sure incoming is working
  this.getIncomingTransactionsForAccount(account)
    .do(x => console.log('incoming transactions', x),

  // added .do() to make sure outcoming is working
  this.getOutcomingTransactionsForAccount(account)
    .do(y => console.log('outcoming transactions', y),

  (incoming, outcoming) => {
    // ... do your calculations
    let result = {
      // results
    };
    return result;
  }

);

It might be good to add temporary .do() side effects to each input streams to see if they are being called and returning results in the first place, especially since the combine block doesn't seem to get called in your previous examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM