baconjs / bacon.js

Functional reactive programming library for TypeScript and JavaScript
https://baconjs.github.io
MIT License
6.47k stars 331 forks source link

Shorthand for filter map #765

Open eguneys opened 4 years ago

eguneys commented 4 years ago

I have this everywhere in code:


eventStream
  .filter(_ => _.props)
  .map(_ => _.props);

I hope there is a shorthand for that.

semmel commented 4 years ago

Not a shorthand but shorter.

stream
.map(_ => _.props)
.filter(Boolean)

I rarely encounter this scenario.

semmel commented 4 years ago

Not being a huge fan of Bacon's method chaining API, I prefer ramda-style auto-curried, data-last functions. And "chaining" them by function composition. This way it is easy to compose your own utility functions without the prototype hassle you would have if you would to extend Bacons native API.

import { curry, pipe } from "ramda"; 
// ramda-style Bacon API
const flatMap = curry((fn, observable) => observable.flatMap(fn));
// use
pipe(
   flatMap(_ => _.props ? Bacon.once(_.props) : Bacon.never())
)(stream);

// or make a utility function
const filtermap = key => 
      flatMap(evt => evt[key] ? Bacon.once(evt[key]) : Bacon.never());
// use
pipe(
   filtermap('props')
)(stream);
raimohanska commented 4 years ago

I've been thinking about moving Bacon from the current "object-oriented" API to data-last functions that you can import separately, like RxJs has been packaged for quite a while already. Would have some benefits including treeshaking and easier extendability (typescript practically destroyed the earlier way of just adding stuff to EventStream prototype).

steve-taylor commented 4 years ago

Previously (before v3), you could do this in Bacon.js:

.filter('.path.to.some.property')

You can use Lodash to get something similar:

import property from 'lodash/property';
.filter(property('path.to.some.property'))

But I wouldn't do this anymore. Best to allow the types to flow and let your TypeScript-powered IDE find potential errors.