Vikas
Vikas

Reputation: 749

Why isn't this promise working?

I'm trying to use promise in following example. I'm learning promise but my first example doesn't work. It prints "Promise didn't work".

Now, what I know is that hide() function takes 400ms to assign value to foo. That's why ajax call wouldn't get the data. So it wouldn't work.

I can resolve this by calling ajax inside the callback of hide, but I want to resolve it using Promise (I suppose this is why promise is used?).

Is there something wrong OR this is not promises are intended to do?

Here's my code:

var foo;
    var res;
    var Prom;
    $("button").click(function(){
        Prom = new Promise(function(resolve, reject){
            $("p").hide(function(){
                foo="YOLO";
            });
            $.ajax({
                url: 'api.php',
                type: 'post',
                data: 'name='+foo,
                success: function(result){
                    res=result;
                    resolve(res);
                },
                error: function(){
                    reject("Promise didn't work");
                }
            });

        });
        Prom.then(function(result) {
          console.log("The PHP response is: ", result);
        }, function(err) {
          console.log(err); // Error: "It broke"
        });
    });
});

Upvotes: 0

Views: 96

Answers (2)

Sandeep Nayak
Sandeep Nayak

Reputation: 4757

You need to create a promise only for the hide function, whereas you are doing it for the entire code block.

Try this instead

var foo;
    var res;
    var Prom;
    $("button").click(function(){
        Prom = new Promise(function(resolve, reject){
            $("p").hide(function(){
                foo="YOLO";
                resolve(true);
            });

        });
        Prom.then(function() {
           //once hidden trigger ajax
           $.ajax({
                url: 'api.php',
                type: 'post',
                data: 'name='+foo,
                success: function(result){
                    res=result;
                    // ajax success
                },
                error: function(){
                    // ajax error
                }
            });

        }, function(err) {
          console.log(err); // Error: "It broke"
        });
    });
});

Upvotes: 1

Jaromanda X
Jaromanda X

Reputation: 1

As $.ajax already returns a promise, and many jQuery animation type methods, including $.hide, can return a promise, your code can be rewritten as follows

var res;
$("p").hide()
.promise() // returns a promise that resolves when hide finishes
.then(function() {
    return "YOLO";
})
.then(function(foo) {
    return $.ajax({
        url: 'api.php',
        type: 'post',
        data: 'name='+foo,
        success: function(result){
            res=result;
        }
    })
})
.then(function(result) {
    console.log("The PHP response is: ", result);
}, function(err) {
    console.log(err); // Error: "It broke"
});

Note, however, that the callback in hide is redundant, because you could just use 'YOLO' in the ajax call anyway!

also note that result in the .then after $.ajax is an array where [0] is the result as you would get in the success callback, [1] is the textStatus of the ajax call, and [2] is the jqXHR object - i.e. these are the three callback arguments to success: function(result, textStatus, jqXHR) except they are in an array, as .then callbacks only receive a single argument

Upvotes: 1

Related Questions