Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

323
Views
How to get results from functions that use concatMap in rxjs?

I calling to two functions: fn1 and fn2. I use concatMap to invoke other after the other.

I don't use exhustMap and switchMap because they lead to nested "callback-hell".

  exhaustMap(() => 
     fn1().pipe(
       switchMap(() => fn2()))))

The one problem is how to get the results of fn1 and fn2 into next function that happens after fn2 is invoked?

stackblitz.com

import { of } from 'rxjs';
import { concatMap, tap } from 'rxjs/operators';
console.clear();

const fn1 = () => {
  console.log('in fn1');
  return of('fn1');
};

const fn2 = () => {
  console.log('in fn2');
  return of('fn2');
};

of(1)
  .pipe(
    concatMap(() => fn1()),
    concatMap(() => fn2()),
    tap({
      next: (a) => {
        console.log({ a }); /// <---- here I want to get fn1, fn2 from the functions.
        console.log('in tap!!!');
      },
      error: () => {
        console.log('in tap error!!!');
      },
      complete: () => {
        console.log('in tap complete');
      },
    })
  )
  
  .subscribe({
    next: (r) => {
      console.log({ r });
    },
    error: (e) => {
      console.log({ e });
    },
    complete: () => {
      console.log('complete');
    },
  });

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

I don't think there's an existing operator that could avoid the "operators-hell", but maybe you can build one that would?

Something like

import { from, ObservableInput, Observable } from "rxjs";
import { concatMap, map } from 'rxjs/operators';

const appendMap =
  <T, R extends ObservableInput<any>>(mapFn: (value: T) => R) =>
  (source$: Observable<T>) =>
    source$.pipe(
      concatMap((value) =>
        from(mapFn(value)).pipe(map((result) => [value, result] as const))
      )
    );

So now you can use it and avoid "operators-hell":

import { of } from 'rxjs';
import { tap } from 'rxjs/operators';

const fn1 = () => of('fn1');

const fn2 = () => of('fn2');

of(1)
  .pipe(
    appendMap(() => fn1()),
    map(([_, fn1Result]) => fn1Result),
    appendMap(() => fn2()),
    tap({
      next: ([fn1Result, fn2Result]) => {
        console.log({ fn1Result, fn2Result });
        console.log('in tap!!!');
      },
      error: () => {
        console.log('in tap error!!!');
      },
      complete: () => {
        console.log('in tap complete');
      },
    })
  )
  .subscribe({
    next: (r) => {
      console.log({ r });
    },
    error: (e) => {
      console.log({ e });
    },
    complete: () => {
      console.log('complete');
    },
  });
about 4 years ago · Juan Pablo Isaza Report

0

You could just pipe in the 2nd concatMap to the fn1() and use map to emit both the values.

of(1)
  .pipe(
    concatMap(() => 
      fn1().pipe(
        concatMap((fn1Value) => fn2().pipe(
          map((fn2Value) => ({
            fn1: fn1Value,
            fn2: fn2Value
          }))
        ))
      )
    )

I've adjusted your Stackblitz

about 4 years ago · Juan Pablo Isaza Report

0

The closest I can think of is here: Stackblitz

const fn1$ = of(1);
const fn2$ = of(2);

fn1$.pipe(
    concatWith(fn2$)
  ).pipe(
      bufferCount(2)
).subscribe(console.log);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!