Q:

RxJS handling closure variables

My scenario is following:
- Reach to database for some object
- After obtaining base object grab it's additional data
- Merge additional data to base object
I wish to write it in pure functional manner (i.e. with no side effects) but so far I'm unable to achieve it:
getMeterPointWithMeterDatabyId(id: number, allowEmpty: boolean = false): Observable<MergeObject> {
    const params = this.getEmptyParams();
    let mp: MergeObject; // This is my enclosed objects I refer to

    return this.masterService.getMasterById(params)
    .concatMap<MergeObject, MergeData[]>((master: MergeObject) => {
      mp = master; // This is side effect generation
      return this.meterService.getMasterData(params);
    })
    .concatMap<MasterData[], MergeObject>((md: MasterData[]) => {
      mp.data = md.slice(); // Even more side effects
      return Observable.of(mp); // Final result generated form impure result
    });

I think I have a ggo understanding of how Rx works when there is no cycle dependency between objects (i.e. my call chain produced A -> B -> C) but I'm loosing my confidence when I need to step back at one processing step to grab some previous data (i.e. A -> B -> A , where A finally contains B)
EDIT: As far a si know, zip operator is doing the trick, but I'd like to know, is it possible to achieve such manually 

A:

If you actually need the base object to query the details (i.e., the requests must happen consecutively), you can do
this.service.getMaster(id)
  .switchMap(master => this.service.getDetails(master)
    // .catch(…) <-- if you want to continue even if fetching the details fails
    .map(details => merge(master, details))
  )
  .subscribe();

The trick is to simply nest the map inside the switchMap, that way master stays in scope without having to jump through hoops.
If the details request is actually independent, you can fire both in parallel using
Observable.forkJoin(
  this.service.getMaster(id),
  this.service.getDetails(id)
    // .catch(…) <-- if you want to continue even if fetching the details fails
)
  .map(([master, details) => merge(master, details))
  .subscribe();

The technique of delinearizing an operator chain, that is transforming
source$
  .switchMap(data1 => transformationA(data1))
  // From here on out, you only see data1
  .switchMap(data2 => transformationB(data2))
  // From here on out, you only see data2
  .subscribe(data3 => …);

into
source$
  .switchMap(data1 => transformationA(data1)
    .switchMap(data2 => transformationB(data2)
    // You can see both data1 and data2 here!
  )
  .subscribe(data3 => …);

is useful quite often in order to keep data from multiple steps in scope, e.g. to combine them. It's definitely something to always keep in mind: you can also nest.

