angular-bacon
angular-bacon copied to clipboard
`$watchAsProperty` may skip values
Because $scope.$watchAsProperty() returns a property that is constructed from a Bacon.Bus, it suffers from this issue.
Compare:
// Note that `$scope.test` does not exist.
var property = $scope.$watchAsProperty('test');
property.onValue(function (value) {
console.log("I will be invoked once with value `undefined`:", value);
});
// Digest loop results in Angular running the watch function on `test`.
$scope.$digest();
to:
// Note that `$scope.test` does not exist.
var property = $scope.$watchAsProperty('test');
// The digest loop is run for whatever reason before the property is subscribed to.
$scope.$digest();
property.onValue(function (value) {
// Even though Angular has executed the watch on `test` (like in the preceding example),
// the new value has been lost because `property` had not been subscribed to yet at that
// point in time.
console.log("I will never be invoked");
});
// No matter how many times the digest loop runs in the future, that initial value for `test` has
// been lost forever.
$scope.$digest();
It may be intended Bacon behavior, but that doesn't mean it should be intended $watchAsProperty behavior.
In my opinion, how one expects $watchAsProperty to behave is very obvious and intuitive: it should represent an Angular scope variable as a Bacon property.
Where $scope.$watch assigns a listener that runs exactly once for every new value of a scope variable, $scope.$watchAsProperty should construct a property that emits a change event exactly once for every new value of a scope variable. Since the idea behind properties is that they hold on to their latest ("current") value, missing or skipping just a single value change causes unexpected behavior even if the property has not been subscribed to yet.
P.S. This issue is related to the similarly motivated #19.
Yeah, I see this issue being referenced in https://github.com/baconjs/bacon.js/issues/536 - I'd love to see a bacon.js -wide consensus to this first instead of creating an angular-bacon specific version which potentially has differing semantics from bacon.js. Then again, AngularJS apps are not exactly set up once and then run, as directives and controllers are not singletons so these streams are created and plugged on-the-go. I'll probably need to muse over this for a few days first.
I ended up with some alternative implementations that work for me. As soon as I have them in a repo on GitHub I will let you know.