1

I need to create a Bacon.Property that gets either true or false if multiple html input contain their correct char. (They all have to be correct, if not, the property needs to be false)

To achieve this, I created an Array of eventStreams via jquery.bacons asEventStream helper and used bacons combineAsArray to create a "allInputsAreCorrect" stream.

And this is when I fail. The "allInputsAreCorrect" immediatly ends. And after ending, it once calls my onValue callback (?). Did I get something completely wrong, or is their a better way to combine all those inputs into one Property?

Here are the corresponding parts from my code, I tried to comment everything as best as possible:

var phraseCorrect,
    phraseStream = Bacon.combineAsArray((function () {
        // Using jQuery.map to convert inputs
        // into an Array of eventStreams:
        return $('.keyphrase-list input')
            .map(mapFromInputToStream);
    }()));

// This is how I would like to create the Property..
// But the Stream doesnt fire, so this is unimportant for now.
phraseCorrect = phraseStream.toProperty(false);

phraseStream
    .onEnd(function () {
        // This gets called immediately..
        // And I dont get why.
        console.log('End?? Why????');
    });

phraseStream
    .onValue(function (values) {
        // This gets called **once**
        // (right after the onEnd logging.. ???)
        console.log('Gets called once', values);
    });

The mapping function that creates the keyup eventStreams:

function mapFromInputToStream() {
    var $input = $(this);

    // I commented out some mapping and filtering.
    // But even without `map` and `filter` it doesnt work.
    return $input
        .asEventStream('keyup');
        // .map(someMapping)
        // .filter(someFiltering);
}

This code logs the following:

End?? Why????
Gets called once [b.fn.b.init[17]]

(there are 17 inputs)

After that, typing anything in one of the html inputs doesnt trigger any callbacks.

I would appreciate if someone could give me an explanation for this behaviour (the immediatly ending stream). But of course, any hints on how to fix this (with bacon.js) are welcome..

zx81
  • 41,100
  • 9
  • 89
  • 105
jukempff
  • 965
  • 6
  • 12

1 Answers1

2

Add a .get() or .toArray() so that you pass a real array to Bacon, not a jQuery object (that is returned by map). Bacon will mistake that for a constant (since it's not instanceof Array), and return an ended, constant property.

var phraseCorrect = Bacon.combineAsArray($('.keyphrase-list input')
                                         .map(mapFromInputToStream)
                                         .get());
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you! I didnt know that jQuery.map doesnt return true arrays... Anyhow, the combined stream *now* doesnt trigger anything, also with `.get` or `.toArray`.. any thoughts on this? – jukempff Jun 23 '14 at 16:24
  • [`jQuery.map`](http://api.jquery.com/jQuery.map/) does, [`jQuery.fn.map`](http://api.jquery.com/map/) doesn't. Notice that `phraseCorrect` (from my code) is not a stream, `combineAsArray` always returns properties right away. Make sure to have your listeners not attached to `phraseStream` – Bergi Jun 23 '14 at 16:28
  • I guess the rest is my problem.. ;) But you answered my question, so I'll mark it as correct! – jukempff Jun 23 '14 at 16:32
  • **Well** everything was correct! I just was too stupid to type in all inputs.. Thanks again :) – jukempff Jun 23 '14 at 16:40