baconjs / bacon.js

Functional reactive programming library for TypeScript and JavaScript

Home Page:https://baconjs.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

One issue about the example in baconjs homepage

PigeonT opened this issue · comments

how can I write the second example in the homepage of baconJS like this? I've no idea how to write here the 'flatMap' function so that I can always chaining the whole things?
baconjs

Keep chaining away. Should probably be something like the following (you only ever really one want subscriber, or one onValue call.

const URL = 'https://myUrl.com';

$('#movieSearch').asEventStream('keyup')
  .debounce(300)
  .skipDuplicates()
  .flatMap(c => {
      return Bacon.fromPromise($.get(URL + c));
  })
  .onValue(c => console.log(c));

I'm not entirely sure with your fromPromise and using the jQuery .get method if it'll return quite the way you want, I'm more used to wrapping all these things in bacon.fromBinder so I can also cancel previous requests as new requests come in.

const getResult = (value) => {
  return bacon.fromBinder(sink => {
    const response = $.get(URL + value)
      .then(result => {
        sink(result.body); // or text or whatever
      });
    
    return () => { response.abort(); }

$('#movieSearch').asEventStream('keyup')
  .debounce(300)
  .skipDuplicates()
  .flatMapLatest(getResult)
  .onValue(c => console.log(c));

Using flatMapLatest ensures that any previous stream returned via this function is be aborted (if .abort is how you do so in jQuery).

Otherwise potentially even though you've got debounce happening here after keyup, previous requests that may still be running/fetching - will continue to do so. It's sometimes why you'll be typing away, finish typing, then 2/3 things flick up in your autocomplete boxes.

Hope that puts you on the right path.

Well put, @darrennolan.

The fromPromise+$.get combo should work quite well too. Or you can just use the fetch API instead of jQuery AJAX as well. The fetch function returns a Promise that you can wrap with Bacon.fromPromise.

thx a lot, very clever solution. What I was confused about is actually the argument in the function passed into flatmap. E.g. I've flatMap((x) => {What means x here actually?}), I searched a lot as well as in docs, but no one explained that.

The x in the function passed to flatMap will be the value from the source stream. Actually in @darrennolan's example it will be the the keyup event, while it should be the current value of the text field. So, I'd modify the example to contain the .map(".target.value") part that was included in the original example.

If you're familiar with Promises, flatMap does the same thing as Promise.then (except it doesn't force a subscription on the stream).