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

Unexpected doAction behaviour in combination with flatMapLatest

raimohanska opened this issue · comments

Why does this trigger doAction twice?

Bacon.constant('constant')
  .flatMapLatest(() => Bacon.constant('flatMapLatest').doAction((val) => console.log('doLog', val)))
  .log('log')

OTOH, this works as expected

Bacon.constant('constant')
  .flatMap(() => Bacon.constant('flatMap').doAction((val) => console.log('doLog', val)))
  .log('log')`

Needs investigation.

The Property.flatMapLatest method uses internally Property::takeUntil, which uses two different subscriptions on the source property, causing the doAction behavior to fire twice.

I patched flatMapLatest to avoid this behavior, but you can still reproduce the double firing of doAction with the following code:

let values = []
let c = Bacon.constant('1')
c.doAction(x => values.push(x))
 .takeUntil(Bacon.never())
 .onValue()
console.log(values)

EDIT: I think I found the minimal test case now.

And actually, you get the same even with this code:

let p = Bacon.constant(1)
  .doLog('doLog')

p.take(1).onValue()
p.take(1).onValue()

The thing is that a Property will fire its current value for any new subscribers. When all subscribers of the property have unsubscribed, it will be kinda reset and the onValue listener will fire again for the same initial value when a new subscriber is added.

So at this moment we'll have to conclude that there's no guarantee that a doAction on a Property will fire exactly once per value.

I'm reverting the patchy fix.