Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return an empty promise

I have a function that returns a jQuery promise. It looks like this:

addBooks(books: Array<Books>) {
    return $.ajax({
        url: '/Books/AddBooks/',
        type: 'POST',
        data: ko.toJSON(books),
        contentType: 'application/json'
    });
}

I do this so I can reuse this function and chain promise callbacks like:

addBooks.done(() => { alert("Books added!"); })

My question is, what if I want to break out of addBooks early and prevent a trip to the server. For example:

addBooks(books: Array<Books>) {

    // An empty array was passed in for some reason.
    // Theres nothing to add so dont try to POST
    if (books <= 0) return null;

    return $.ajax({
        url: '/Books/AddBooks/',
        type: 'POST',
        data: ko.toJSON(books),
        contentType: 'application/json'
    });
}

My example will not compile because my chained done callback example is expecting addBooks to return a promise object, not null. How can I return an empty promise (or whatever the correct object is I should return in the situation)?

like image 724
Jonathan Eckman Avatar asked May 02 '15 16:05

Jonathan Eckman


People also ask

What does empty Promise mean?

Empty-promise definition (idiomatic) A promise that is either not going to be carried out, worthless or meaningless.

What does empty Promise resolve do?

The Promise.resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise.resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.

How do I return a Promise?

Promises don't "return" values, they pass them to a callback (which you supply with . then()). It's probably trying to say that you're supposed to do resolve(someObject); inside the promise implementation. Then in your then code you can reference someObject to do what you want.


3 Answers

How can I return an empty promise (or whatever the correct object is I should return in the situation)?

Yes, an "empty promise" is appropriate here, if you mean a promise that is already fulfilled with nothing (undefined, null).

The jQuery syntax to create such is using $.when with a single (or no) argument:

if (books <= 0) return $.when(null);
like image 174
Bergi Avatar answered Nov 07 '22 23:11

Bergi


You can return a resolved promise: Instead of

if (books <= 0) return null;

use

if (books <= 0) return $.Deferred().resolve();

Beware, though, that jQuery's Promise API does something surprising: Sometimes it calls your done/then/etc. callback synchronously with the done/then/etc. call, sometimes it doesn't. Most promises libraries ensure that the call is always asynchronous, even if you're calling done/then/etc. on a resolved promise. jQuery doesn't, so you get subtle differences.

For instance, this code:

addBooks(() => console.log(1));
console.log(2);

...will log

2
1

...if you did the ajax call, but

1
2

...if you returned a resolved promise.

like image 20
T.J. Crowder Avatar answered Nov 08 '22 00:11

T.J. Crowder


From https://api.jquery.com/jquery.when/

If you don't pass it any arguments at all, jQuery.when() will return a resolved promise.

e.g.

if (books <= 0) return $.when();

and, if you need a value that is not undefined passed on:

If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately. The doneCallbacks are passed the original argument.

e.g. an empty array is passed on:

if (books <= 0) return $.when([]);

e.g. an empty object is passed on:

if (books <= 0) return $.when({});
like image 3
Gone Coding Avatar answered Nov 07 '22 22:11

Gone Coding