-1

I have a component X that needs an outcome of subscription to multiple observables and than send this outcome to component Y. These are the observables that must be somehow united to produce the result that I need:

  1. getChosenCityId (behaviourSubject) // once I have id, I can get city like so:
  2. getCityById(id) (result of a http call)

// Once I have the city, which is an object, I need its property - cityLocation

  1. getCitiesByLocation(cityLocation) (result of a http call) // cityLocation from the previous line
  2. getNearbyCities. (behaviorSubject) Returns a boolean. If it is true, I need

a)

  • citiesByLocation (4.)
  • chosenCityId (1.)

and if it is false, I need:

b)

  • city (2.)
  • chosenCityId(1.)

a) and b) are the outcomes that I need to send to the component Y (with next). How can I chain all these observables?

Mandy
  • 107
  • 1
  • 2
  • 9
  • 1
    see [this](https://stackoverflow.com/questions/35268482/chaining-rxjs-observables-from-http-data-in-angular2-with-typescript)..actually, there are lot of questions regarding chaining observables, surely some question will help you. – Ramesh Reddy Dec 13 '19 at 17:21

2 Answers2

3

Use a higher map operator like switchmap:

nearbyCities$ = getChosenCityId.pipe(
  switchMap(id => getCityById(id)),
  switchMap(city => getCitiesByLocation(city.location)),
);
MoxxiManagarm
  • 8,735
  • 3
  • 14
  • 43
3

kind of hard to interpret this but something like...

this.getChosenCityId.pipe( // get id
  switchMap(id => this.getCityById(id)), // fetch the city
  withLatestFrom(this.getNearbyCities), // with the latest from get nearby
  switchMap(([city, getNearby]) => 
    getNearby // if get nearby, then get cities by location and map
      ? this.getCitiesByLocation(city.location).pipe(map(nearbyCities => ({city, nearbyCities})))
      : of({city}) // else just return the city
  )
).subscribe(result => console.log(result))

the set up would be a little different if you also want to automatically update if getNearbyCities changes:

combineLatest(this.getChosenCityId, this.getNearbyCities).pipe( // run when either emits
  switchMap(([id, getNearby]) => 
    this.getCityById(id).pipe(
      switchMap(city => 
        getNearby 
          ? this.getCitiesByLocation(city.location).pipe(map(nearbyCities => ({city, nearbyCities})))
          : of({city})
      )
    )
  )
).subscribe(result => console.log(result))
bryan60
  • 28,215
  • 4
  • 48
  • 65
  • Thank you very much, that seems very much what I've asked for!! I'll try it and let you know! I just don't understand this line (sorry, very new to this..):this.getCitiesByLocation(city.location).pipe(map(nearbyCities => ({city, nearbyCities}))) ---- getCitiesByLocation is also an observable, can I subscribe to it in this way? Thank you very much for your time and very useful reply! – Mandy Dec 13 '19 at 17:44
  • 1
    switchMap is handling the subscribe, there's just an inner map attached to it to keep the city data – bryan60 Dec 13 '19 at 17:46
  • Ok, got it! Thank you again! Yes, I need to automatically update it if either chosenId changes or getNearbyCities changes ( should have mentioned it sooner..). – Mandy Dec 13 '19 at 17:48
  • But I think that both are changing at the same time, so it shouldn't be a problem.. – Mandy Dec 13 '19 at 17:50
  • 1
    i changed it to use combine instead – bryan60 Dec 13 '19 at 17:51
  • Great, thank you really (I'll check again to see if both are needed, but I understand the concept!)! I've been trying to figure it out for ages, with no luck.. You saved me. – Mandy Dec 13 '19 at 17:58