Reputation: 2182
I just wrote:
function getQtyFor(state,down) {
var promise = new RSVP.Promise( function (fulfill, reject) {
if (!down && (state=='bottle' || state=='pumped')) {
doDialog('volume')
.then ( validateVolume ,
function () { hideDialog('volume');
return getQtyFor(state,down); } )
.then ( function (q) { hideDialog('volume');
fulfill(q); },
function (e) { hideDialog('volume');
alert("Bad input "+e);
return getQtyFor(state,down); } )
} else fulfill(0);
});
return promise;
}
in which you can see two recursive calls. I'm finding that the first works as expected, and the second goes round in circles as expected, but I never get a 'fulfillment' after the second is used. In other words, I can run around in circles either by cancelling the dialog (first recursion) or by entering values that the validator doesn't like (second recursion.) In the former case, after I finally decide to hit OK, the waiting "then" will run and drop stuff in my database. But if I go round in circles by entering silly values and then finally enter a sensible value, then the waiting "then" will not run, and neither will it's rejection handler.
I kinda suspect the problem is that I'm fulfilling a different promise than the one with my handlers attached, but I still don't see why it works one way and not the other.
I guess you'll need the rest of the code to reproduce this so it's at http://quorve.com/rsvpissue/babylog.html. Here's the aforementioned waiting "then":
function stick(down) {
return function(ob) {
return getQtyFor(ob.attr('id'), down)
.then( getStickyFields(down, ob), alert ) //NEITHER REACHED AFTER FAILED VALIDATE
.then( db_insert('transitions') )
.then( function() { updateButtonAppearance(down)(ob); } , alert);
}
}
and the stuff called from the problematic recursive function:
function doDialog(log) {
var promise = new RSVP.Promise( function(fulfill, reject) {
$('#'+log).dialog({
dialogClass: "no-close",
modal: true,
buttons: {
"OK": function() { fulfill($(this)); },
"Cancel": function() { reject(); }
}
});
});
return promise;
}
function validateVolume(form) {
vol = form.find("[name=qty]").val();
if ( vol > 200 ) {
throw("vol"); }
return vol;
}
Steps to reproduce:
Use Chrome cos it uses WebSQL. (I know it's depped, but let's not change the subject.)
Go to http://quorve.com/rsvpissue/babylog.html
Click Zach's bottle (depressed button) and hit cancel in the dialog. The dialog persists until you hit OK, after which, you see a new transition bottom right representing the end of the drinking session with a quantity of 150ml. You were using the first recursive call when you were pressing cancel.
Reload the page (which resets the DB.) Click the bottle as before but push the slider to the top (no baby can drink that much) and press OK. Dismiss the nag box and the dialog reappears. Repeat if you like. Push the slider to a lowish value and press OK. Now you see the problem: the dialog disappears, so we've dropped out of the recursion, but the button and DB are not updated because the continuation is not called and neither is its rejection case.
Is this a bug in RSVP or have I misunderstood promises?
TIA, Adrian.
Upvotes: 1
Views: 173
Reputation: 2182
Sussed it! I should say:
fulfill(getQtyFor(state,down))
rather than
return getQtyFor(state,down)
for the recursive call.
Upvotes: 2