Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - How to combine multiple "valueChanges" observables into one

How can I combine the following subscriptions into one?

    this.form.get("type").valueChanges.subscribe(() => {
        this.calcFinalTransports();
    })
    this.form.get("departure").valueChanges.subscribe(() => {
        this.calcFinalTransports();
    })
    this.form.get("destination").valueChanges.subscribe(() => {
        this.calcFinalTransports();
    })
    this.form.get("stations").valueChanges.subscribe(() => {
        this.calcFinalTransports();
    })
like image 540
Michalis Avatar asked Dec 12 '17 20:12

Michalis


2 Answers

You have a few choices depending on what output you expect. You may want to read this article:

  • Learn to combine RxJs sequences with super intuitive interactive diagrams

If you just want to get notified whenever any of the value changes use merge:

import {merge} from "rxjs/observable/merge";

merge(
    this.form.get("type").valueChanges,
    this.form.get("departure").valueChanges,
    this.form.get("destination").valueChanges
    this.form.get("stations").valueChanges
).subscribe(() => this.calcFinalTransports());
like image 82
Max Koretskyi Avatar answered Nov 08 '22 13:11

Max Koretskyi


If want to use single Data observable pattern and combine multiple observables into one observable, then combineLatest may come as useful.

PesudoCode

userNameAndEmail$=this.userNameAndEmail().pipe(startsWith(null));
userAddressDetail$=this.userAddressDetails().pipe(startsWith(null));
userMiscDetails$=this.userMiscDtls();


completeUserData$=combineLatest([userNameAndEmail$,userAddressDetail$,userMiscDetails$])
.pipe(map(([userNameAndEmail,userAddressDetail,userMiscDetails])=>{  
 return {userNameAndEmail,userAddressDetail,userMiscDetails};  } ));

However, there are certain conditions. https://www.learnrxjs.io/learn-rxjs/operators/combination/combinelatest

like image 2
Yogesh Sanchihar Avatar answered Nov 08 '22 14:11

Yogesh Sanchihar