question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Remove secondary mappings for flattening operators

See original GitHub issue

For operators like mergeMap, switchMap, concatMap, etc, we have a secondary selector. It’s not used a lot in practice that I’ve seen. Originally, it added a lot of value in terms of perf because it prevented a closure… however, in practice it makes it harder to isolate errors from observation chains, and in a world with Turbofan, I’m not sure the performance benefit is there. We could eliminate a good amount of code in the library written to support this.

Use and Alternatives

Observable.of(1, 2, 3).mergeMap(a => range(0, a), (a, b) => a + b);

/// which is mostly the same as

Observable.of(1, 2, 3).mergeMap(a => range(0, a).map(b => a + b))

// however if there's an error in that second map, you're forced to kill the whole observable...

Observable.of(1, 2, 3)
  .mergeMap(a => range(0, a), (a, b) => { throw new Error('lol') })
  .catch(err => empty())

// rather than this, which is much more common

Observable.of(1, 2, 3)
  .mergeMap(
    a => range(0, a)
      .map(b => a + b)
      .catch(err => empty())
  )


Proposed Change

Eliminate the second argument to mergeMap, concatMap, switchMap, et. al. and instruct people to use .map within the projection function if they want a secondary level of mapping.

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:3
  • Comments:16 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
benleshcommented, Oct 11, 2017

With regards to that argument I made above, the problem isn’t so much with the “throwable” part as it is in patterns like you’d see in redux-observable or ngrx, where you might have something that throws, moving the catch outside of the flattening operation will kill your entire stream, but catching it inside gets weird with that secondary map:

// redux observable epic or ngrx effect
action$ => action$.ofType('LOAD_DATA')
  .switchMap(() => 
    makeAjaxCall()
      .catch(err => {
        console.log('ajax failed')
        return Observable.of({ type: 'AJAX_ERROR', err })
      }),
   (responseOrError) =>
    responseOrError.type === 'AJAX_ERROR'
      ? responseOrError
      : { type: 'AJAX_RESPONSE', response: responseOrError }
  )

As you can see it gets ugly fast… But by just using a map it cleans it up.

// redux observable epic or ngrx effect
action$ => action$.ofType('LOAD_DATA')
  .switchMap(() => 
    makeAjaxCall()
      .map(response => ({ type: 'AJAX_RESPONSE', response }))
      .catch(err => {
        console.log('ajax failed')
        return Observable.of({ type: 'AJAX_ERROR', err })
      })
  )
1reaction
wmaurercommented, Oct 10, 2017

I’ve not a lot to technically add to this discussion. I can only say that I very often use the secondary selector, and my team has followed my practice. This change would cause us to have to touch a lot of files across quite a number of projects. However according to your observations, we’re exceptions to the rule …

Read more comments on GitHub >

github_iconTop Results From Across the Web

Flattening map operators in RxJS
In RxJS We have four flattening map operators: ... acts the same as concatMap and mergeMap in the context of flattening and mapping....
Read more >
Learn RxJS switchMap, mergeMap, concatMap and ... - Medium
There are 4 “MAPPING + FLATTENING” Operators. let's call them “mappening” operators from now on —. (1) mergeMap() , (2) switchMap() ...
Read more >
RxJs Mapping: switchMap vs mergeMap vs concatMap vs ...
Learn in-depth the merge, switch, concat and exhaust strategies and their operators: concatMap, mergeMap, switchMap and exhaustMap.
Read more >
Flattening Operators in RxJS 101 - JavaScript Marathon
Learn about mergeMap, concatMap, switchMap, exhaustMap, and which ones to use when with Ben Lesh, author of RxJSIf you enjoyed these ...
Read more >
Using Data Flow Operators - Oracle Help Center
In Data Integration, data flow operators represent input sources, output targets, and transformations that can be used in a data flow.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found