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

Initial Events of a subscribed Property are replayed in a later Subscription which is debounced

semmel opened this issue Β· comments

This error took me hours to hunt down to this simplified test case 😣

The initial value of the source property appears twice in the derived stream:

var source = Bacon.constant("Y"); 
var unlog = source.log("source"); //necessary that original is already subscribed
var timer = setTimeout(function() {
   var derived = 
      source.doAction(x => console.log(`doAction:${x}`))
      .debounce(100);  //necessary
   derived.log("derived");
}, 20); //any timeout will do
// Output:
// source – "Y" 
// source – "<end>"
// doAction:Y
// doAction:Y  <--- DUPLICATE VALUE!
// derived – "Y" 
// derived – "<end>" 

Tested in Node.js and the Browser with the new ES6 build.

On closer inspection it is indeed the initial event (Perhaps getting "bounced" too often by PropertyDispatcher.subscribe, as commented in propertydispatcher.ts?)

var source = Bacon.constant("Y"); 
var unlog = source.log("source");
var timer = setTimeout(function() {
   var derived = source
     .withStateMachine([], (acc, event) => {
	   if (!event.hasValue) { return [acc, [event]]; }
	   console.log(`isInitial=${Bacon.isInitial(event)}, value=${event.value}`);
	   return [event.value, [event]];
      })
      .debounce(100);
   derived.log("derived");
}, 20);
// ...
// isInitial=true, value=Y
// isInitial=true, value=Y
// ...

Unfortunately the quick workaround filtering with .skipDuplicates() is not possible, since it's implemented to let Initial events pass. However with .withStateMachine it's possible to write your own .skipDuplicates.

It's not obvious to me how to fix it: PropertyDispatcher.subscribe, UpdateBarrier and stuff are pretty core Baconjs.
πŸ˜•

Is fixed in 3.0.12. The problem was in addPropertyInitValueToStream which had two separate subscriptions to the source Property. It's now called transformPropertyChanges and avoids the double subscription.

@raimohanska Thanks for the quick fix!
I am very glad! πŸ˜„
Still have to run my tests though.. 🀞