0

I am building an editor that lets a user pick 1 account from a set of accounts (aka a Chart of Accounts (COA) )

The author can define the type/subtype that needs to be selected and the editor should offer only choices that meet this preference.

There are 4 steps:

  1. Take the Type list and the SubType list, compare those to the set of real life T/STs and return matches (not every type and every subtype make a valid combination - sync)
  2. Fetch the complete COA from the database (async)
  3. Slice the COA based on the allowed T/ST combinations (sync)
  4. Populate the config object with the resulting data and return it as an observable

I feel/believe what I have here is a reactive solution.

I have seen/read many articles on using switchmap for this type situation.

This video has been very helpful to me. https://www.youtube.com/watch?v=Byttv3YpjQk&t=1148s

I think switchmap is indicated over combineLatest as the steps are dependent on the data from previous steps.

The challenge I am facing is that I have coded these as separate statements.

If I try to use the data from the first call (named a_tst) in the final observable, I can not.

This is not a blocking issue for me as I do not NEED to reach that far back in this particular case. Next time there may be a need...

I am also capturing the data at each step in the config data structure which seems to be a common practice... so maybe that is the answer?

MY QUESTION - Is there a way to string the switchMaps together such that the trailing switchMaps can reach all the way back through the chain and access the emitted values from the earlier calls?

Still learning rxjs. Any comments or suggestions would be appreciated...

public hydrate_COA_Editor_Config(config_: COA_Editor_Config, title_: string) : Observable<COA_Editor_Config> {
  const debug: boolean = false;
      
  if (debug) console.log('svc 0.1', title_, config_);

  // get the allowed Type/Subtype combinatinos from the config data structure passed in by caller
  const allowedTST$ = this.get_coa_Allowed_TST_List(config_.AccountTypes, config_.AccountSubTypes);
             
         
  const Accounts$ = allowedTST$.pipe(
    tap(a_tst => {
      if(debug) console.log('1.0', title_, 'allowed tst', a_tst);

      config_.allowed_TST = a_tst;
    }),
    // ask the service for ALL accounts available for this project
    switchMap(a_tst => this.getCOAByProjectId(config_.projectId))
  );   
    
  const allowedAccounts$ = Accounts$.pipe(
    tap(acctHeader => {
      if(debug) console.log('svc 2.0', title_, 'all accts', acctHeader.Accounts);

        // myAccounts = acctHeader.Accounts;
    }),
    // find the set of Accounts which match the caller's indicated types/subtypes
    switchMap(acctHeader => this.get_coa_Allowed_Account_List(acctHeader.Accounts, config_.allowed_TST.items))
  );
    
  // return the config as an observable. It has now been populated w/ all the data needed to do its job.
  const config$: Observable<COA_Editor_Config> = allowedAccounts$.pipe(
    tap(a_accts => {
      // if(debug) console.log('3.0', title_, a_accts);

      config_.allowedAccounts = a_accts;
      config_.hydrated = true;
      // at this point, we have turned the users wishes (allowed types, subtypes) into a list of accounts that match those wishes
    }),
    switchMap(accts => of(config_))
  );
            
  return config$;
}
Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
greg
  • 1,673
  • 1
  • 17
  • 30
  • Does this answer your question? [How to pass results between chained observables](https://stackoverflow.com/questions/63386585/how-to-pass-results-between-chained-observables) – BizzyBob Feb 21 '23 at 14:06
  • @bizzybob, it looks like it might. – greg Feb 21 '23 at 17:25

1 Answers1

1
obs1$.pipe(
  switchMap(result1 => obs2$),
  switchMap(result2 => obs3$), // result1 not available
  switchMap(result3 => obs4$), // result1 and result2 not available
)

If you nest the switchMap on the next observable's pipe

obs1$.pipe(
  switchMap(result1 => obs2$.pipe(
    switchMap(result2 => obs3$.pipe( // result1 still available
      switchMap(result3 => obs4$)  // result1 and result2 still available
    )
  )
)
Adrian Brand
  • 20,384
  • 4
  • 39
  • 60