baconjs / bacon.js

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

add observable.becoming(value) #468

Open dylemma opened 9 years ago

dylemma commented 9 years ago

I've found myself doing this pattern for the third time, and after searching the docs for a while I haven't found anything that has the same effect:

var fireWhenPropBecomesFalse = someBooleanProp
    .slidingWindow(2, 2)
    .filter(function(win){ return win[0] && !win[1] })
    .map(true)

Basically I only want the resulting stream to fire when the input property/stream becomes false.

observable becoming value

My suggestion is to add a becoming function to replace the snippet above:

var fireWhenPropBecomesFalse = someBooleanProp.becoming(false)

If such a method already exists, could someone please point me to it? If not, I would be open to making a PR to add it.

phadej commented 9 years ago
var fireWhenPropBecomesFalse = someBooleanProp
  .skipDuplicates()
  .filter(function (x) { return x === false; });
dylemma commented 9 years ago

@phadej That actually doesn't have the behavior I described. When the property is false to start with, it fires an initial event. becoming would only fire when the property transitions to your value from some different value, so it would not fire that initial event.

bleadof commented 9 years ago

Wouldn't .toProperty(false) solve it?

-----Original Message----- From: Dylan Halperin notifications@github.com To: "baconjs/bacon.js" bacon.js@noreply.github.com Sent: Fri, 14 Nov 2014 23:17 Subject: Re: [bacon.js] add observable.becoming(value) (#468)

@phadej That actually doesn't have the behavior I described. When the property is false to start with, it fires an initial event. becoming would only fire when the property transitions to your value from some different value, so it would not fire that initial event.


Reply to this email directly or view it on GitHub: https://github.com/baconjs/bacon.js/issues/468#issuecomment-63130417

dylemma commented 9 years ago

The intent is to produce an EventStream rather than a Property. The actual values fired by the resulting stream are unimportant; I'm interested in the fact that the event fired. I suppose if it were to be a Property, I'd expect it to be true at the moment when the observable transitions from [not value] to [value], then instantly go back to false.

raimohanska commented 9 years ago

I think @dylemma's implementation is fine and it could easily be included in Property.prototype, but what I'm not so sure about is how often people would need this. So, should this be included in the core?

mhelvens commented 9 years ago

For what it's worth, I'm also having to do this a lot.

raimohanska commented 9 years ago

Hmm. what about just obs.skipDuplicates().skip(1).filter(function(x) { return x === false }) :)

mhelvens commented 9 years ago

Yup! I'm doing something similar. It's just nice if it has a short notation.

Whether you should put it in the core? I don't know. It's definitely handy to have in the FRP toolkit, but I'm happy defining this in my own code. I'm just responding to your earlier comment, about how many people would use this.

dylemma commented 9 years ago

LGTM

So I guess to make it work for values other than false, it would probably look something like

Observable.prototype.becoming = function(value, comparator){
  var c = comparator || function(e){ return e === value }
  return this.skipDuplicates().skip(1).filter(c)
}