0

I have a widget <input type='file' style='display:none' id='foo' /> and some code that opens the dialog like this

$("#foo").click();

Now I need to set up some code so it runs after the user makes a selection and closes the dialog.

I understand that this is promise pattern but I'm not sure how to go about writing a promise. Could someone give me some guidance? It's no problem to put a change handler on the input widget but I need to code up something like this:

$("#foo").click().then(function(){
  $("#theForm").submit();
});

As I understand promises the case where the postcondition is met (user selects a file and clicks OK) is called resolved and there's another name that just now eludes me for the case where the postcondition isn't met.

Those of you who are about to suggest that I do this

$("#foo").change(function(){
  $("#theForm").submit();
}

I am aware of this solution but it doesn't teach me anything about writing promises.

Peter Wone
  • 17,965
  • 12
  • 82
  • 134
  • Take a look at [jquery promise()](https://api.jquery.com/promise/) – shawnzhu Mar 30 '14 at 14:13
  • If you're looking for a functional interface for coding events - check out FRP, and mainly BaconJS, it builds all the things you want on top of jQuery and it's pretty nifty, I'm a promise proponent but I believe it provides more solid abstractions than just a promise for functional UI coding. – Benjamin Gruenbaum Mar 30 '14 at 15:03
  • I don't think this is a duplicate *question*. Certainly the other question's answer is appropriate for this question but they come at it from different frames of mind that produce different search terms. I think the value of this question lies in the alternate search vector it supports. Since it continues to serve that purpose even when marked duplicate, I guess we're done here, but I wish there were another tag "equivalent". – Peter Wone Apr 01 '14 at 23:11

2 Answers2

1

There's ample documentation on promises out in the world, but here's the skinny:

var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

and then:

promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error: "It broke"
});

http://www.html5rocks.com/en/tutorials/es6/promises/ that might help! good luck

panzhuli
  • 2,890
  • 6
  • 33
  • 46
  • Bergi's answer is pretty good but this is exactly what I was looking for, especially the tutorial. Just after posting the question I found an article on the subject on msdn but it's a bit IE specific. – Peter Wone Mar 30 '14 at 22:16
0

You need to use a Promise constructor, which will give you the ability to resolve the promise:

var p = new MyLib.Promise(function(resolver) {
    $("#foo").one("click", resolver);
}); // a promise that resolves with the next click on #foo
p.then($.fn.submit.bind($("#theForm"))); // or whatever

With jQuery, you'd need to use the Deferred pattern:

$.fn.nextEvent = function(type) {
    var d = new $.Deferred();
    this.one(type, function() {
        d.resolveWith(this, arguments);
    });
    return d.promise();
};

$("#foo").nextEvent("click").then(function(e) {
    $("#theForm").submit();
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you; like everyone else I do use jQuery so I shall take advantage of your link on the Deferred pattern. – Peter Wone Mar 30 '14 at 22:17