I have a form, which has many image urls - the back-end persists url strings and the images are uploaded directly to S3. I'd like to use Bacon.js streams to handle disabling/enabling the form's submit button while uploads are in-progress.
I've tried various approaches (using a stream of streams of Bacon.fromPromises, using a stream of fromPromise-d deferreds and a bus of raw deferreds and trying to manually diff the two) but haven't found a solution that a) works as intended and b) feels like I'm not fighting the library.
This is where things stand, but as noted, the submit button is prematurely re-enabled.
function toResultStream(promise) {
return Bacon.fromPromise(promise)
}
var deferreds = $('a').asEventStream('click', function (event) {
event.preventDefault();
var deferred = $.Deferred();
// simulate upload
setTimeout(function () {
deferred.resolve(true);
}, _.random(200, 1600))
setTimeout(function () {
deferred.rejectWith(false);
}, _.random(200, 1600))
return deferred;
});
deferreds.onValue(function () {
$('#submit').attr('disabled', true);
})
// only takes completed deferreds into consideration
var ongoingSearch = deferreds.flatMap(function (d) {
return toResultStream(d);
})
.mapError(true)
.onValue(function () {
$('#submit').attr('disabled', false);
});
*Update
@mjs2600's answer was enough to nudge me towards a solution.
Here's what I ended up doing:
var bus = new Bacon.Bus();
var deferreds = $('a').asEventStream('click', function (event) {
// ...
bus.push(-1);
// ...
});
var ongoingSearch = deferreds
.flatMap(toResultStream)
.mapError(1)
.merge(bus)
.scan(0, function (memo, n) { return memo + n; })
.onValue(function (value) {
var disabled = value < 0;
$('#submit').attr('disabled', disabled);
});
I know using Buses is frowned upon, so if anyone has a suggestion as to how I could achieve the same behavior with streams, I'd very much like to see it.