Function returns a string instead of a prefix

Asked

Viewed 390 times

3

The code below returns a promise:

function getDealerships(region) {
    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

So I can wait for the server reset and process the result:

var dealerships = getDealerships('sul');
dealerships.done(function(data){
    //...
});

The problem is that I need to implement a simple cache system to prevent the server from being consulted if the user chooses the same region:

var dealershipsCache = [];

function getDealerships(region) {
    if ( region in  dealershipsCache )
        return dealershipsCache[region];

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

Note that if the region is cached, its value is returned, but what is expected is a promise and not a string.

How to solve the problem?

2 answers

2


You have to create a "fake" Promise, ie that gives immediate return if region in dealershipsCache give real, to getDealerships always give a Promise as a result.

You can do it like this:

var dealershipsCache = [];

function getDealerships(region) {
    return new Promise(function(res, fail) {
        if (region in dealershipsCache) {
            res(dealershipsCache[region]);
        } else {
            $.ajax({
                method: "GET",
                url: "/api/v1/dealerships?region=" + region,
                success: function(response) {
                    res(response);
                }
            });
        }
    });
}

If you need to use technology prior to Promises, and so support older browsers, you can do so, with callbacks:

var dealershipsCache = {};
function getDealerships(region, done) {
    if (region in dealershipsCache) {
        return done(dealershipsCache[region]);
    } else {
        $.ajax({
            method: "GET",
            url: "/api/v1/dealerships?region=" + region,
            success: function(response) {
                done(response);
            }
        });
    }
}

and then you call it so:

getDealerships('brazil', function(res){
    // e aqui podes usar a resposta
});
  • I made a similar solution in angular. Several calls that were made in HTTP I remade with a Promise that returned the same object Sponse, worked well

  • It is worth remembering that you have to be careful so that the fail be called, otherwise there will be a silent failure in the execution of Promise.

  • Sergio, the documentation does not work in IE: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Browser_compatibility and I really need to consider IE.

  • See if that answer help you.

  • @Filipemoraes put together a solution for older, old-fashioned browsers (which I still prefer today).

1

To turn a value into a Promise that there was success of response, just you encapsulate the value with Promise.resolve.

var dealershipsCache = [];

function getDealerships(region) {
    if ( region in  dealershipsCache )
        return Promise.resolve(dealershipsCache[region]);

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

Solution with jQuery.Deferred:

var dealershipsCache = [];

function getDealerships(region) {
    var defer = null;
    if ( region in  dealershipsCache ) {
        defer = $.Deferred();
        defer.resolve(dealershipsCache[region]);
        return defer.promise();
    }

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

Solution with $.fn.promise [NOTE: in some older versions this solution will not work):

var dealershipsCache = [];

function getDealerships(region) {
    if ( region in  dealershipsCache ) {
        return $(dealershipsCache[region]).promise().then(function(elements) {
          return elements[0];
        });
    }

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}
  • but according to the documentation, Promise does not work in IE: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Browser_compatibility

  • Friend, your question asks for Promise, not "Promise from jQuery", you better ask your question then... but anyway, until which version of IE need to support? See if this fits: https://github.com/stefanpenner/es6-promise

  • Gabriel, is there in the jquery tag, including the example uses jquery, which is not a precedent.

  • The cache must be the value itself, it cannot be the "jQuery Promise"?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.