Closed myndzi closed 9 years ago
I don't understand your example completely as there obviously some parts are missing, but it looks like it should work if you add .onValue
subscriber to the item
stream. Also it's not clear what you mean when saying "works as expected", what is expected result here? Is something should be printed to console for example? I mean I don't see any side effects defined in your code. As long as there is no subscribers nothing is running, this is one of key features of Kefir.
Oh, sorry. Yes, there is an .onValue subscriber on the item stream; If I remove 'location' from the zip, it works as expected. If I add 'location', nothing is ever emitted until I have a listener on the location property. They both come from the same source stream, and I've verified independently that 'hrefs' and 'innerText' emit data even when the zip doesn't.
What I expect is for it to emit a line for every matching value for 'ul.results a', but to include the current value of 'location' along with it. It does this, but only if I separately bind a dummy subscriber to location.
If you have IRC or Skype or something, get ahold of me (myndzi on either) and I can get you the full code so you can see what I'm running into?
P.S. I tried with fromBinder also but no difference. I'm not sure entirely what the docs mean by 'control over the active state' but I don't see any way with fromBinder to force it into the 'active state'
The "control over the active state" means that .fromBinder
allows you to know when first subscriber is added to the stream that you created and when the last one is removed.
The reason why your code is not working might be is because you are using emitters. Consider this example:
var a = Kefir.emitter();
var b = a.toProperty();
a.emit(1); // the `b` property will not get this value because it not listening to `a` yet.
// It will begin to listen to `a` only when the `b` itself get first subscriber
b.log(); // will not print anything as `b` didn't get the `1` value
You can solve this, using the .fromBinder
method:
var a = Kefir.fromBinder(function(emitter) {
// When we inside this function, it means that `a` has a subscriber, in this case the `b` property subscribed to `a`
emitter.emit(1);
});
var b = a.toProperty();
b.log();
You can read more about active state in docs https://pozadi.github.io/kefir/#active-state (especially the note section)
Try to rewrite you code using .fromBinder
method, if it still won't work please let me know.
Okay, so I've worked it out. You are correct in that it was a sync/async problem; the trouble was that I had once source feeding multiple values -- and I was only subscribing to/pulling from the header value in the callback of the other one, which left the subscription until after the data had occurred.
The fix is to do things what I assume is more properly, by defining each of the data sources and combining them; the combining step is synchronous with the definitions of the data sources, so it ensures that they all kick off at the start of the origin stream.
New code looks something like this:
var location = select(tokenized, '#header span.city')
.flatMap(innerText)
.toProperty();
var item = select(tokenized, 'ul.results a')
.flatMap(function (obs) {
var hrefs = obs.flatMap(attr('href')),
innerText = obs.flatMap(innerText);
return Kefir.zip([href, innerText]);
});
var combined = Kefir.combine([ location, item ], function (l, i) {
return {
location: l,
href: i[0],
text: i[1]
};
});
combined.onValue(function (a) {
console.log(a);
});
I'm trying to gather data from an html document; some of the data is static or periodic, but at the lowest level I want to associate these values with items in a list. I've created some helpers to give me streams and data, but I'm having some difficulty when combining them.
Example: in the header of the page is a span containing a location. It occurs only once on the page, but it occurs before any of the list items I'm interested in. I do something like this:
Run as-is, I get nothing. But if I call
location.onValue(function () { });
it works as expected. I would expect Kefir.zip to act as a subscriber on 'location', but it appears not to. Is this a bug or intentional? What should I be doing instead, if intentional?