1

I was having an obsolete JS library which was making API call Synchronous for which I decided to write JS function which can make them Async using jQuery.

In the following code the getData function is to be a generic function which makes API calls according to params passed and then extract data from the received XML/JS.

The second call(getAllData2) needs values from the result set of getData so I need a callback kind of thing in which the subsequent call can be made after the data is available from the 1st call. Can this be achieved without the ajax success call back as I want getData function to remain generic.

I had tried jQuery promises but that gives me the raw data of the call instead of the processed one which I will have to process in each of the done callback separtely.

getData(param1,param2..){
  var retData     = {};
    ......Param dependent code here..
    jQuery.ajax({
            url:....,
            .......
            success: function(resp){
                if(resp.length > 0){
                jQuery.each(resp,function(key,val){
                    var i = 0;
                    var retObj = {};
                    jQuery.each(val,function(k,v){
                        retObj[k] = v;
                        i++;
                    });
                    retData[key] = retObj;
                });             
            }
                ---Process recieved XML/JS and Insert values in retData here--
            }
    });
    return retData;
}

var getAllData  = getData(x,y);
var getAllData2 = getData(a,b); // this call needs param from getAllData.

Please suggest.

Thanks

techie_28
  • 2,123
  • 4
  • 41
  • 62

1 Answers1

3

Promises are indeed what you should be using.

That will allow you to structure your logic like this:

function processResult(resp) {
    var retData = {};
    if(resp.length > 0){
        jQuery.each(resp,function(key,val){
            var retObj = {};
            jQuery.each(val,function(k,v){
                retObj[k] = v;
            });
            retData[key] = retObj;
        });  
    }
    return retData;
}

getData(x, y)
.then(function (result) {
    var processed = processResult(result);
    return getData(processed);
})
.then(function (result) { // result is the result of the second getData()
    // use result
});

If you want to do pre-processing of the results in your getData() function, again you can do this with promises:

function getData(param1,param2..) {
    ......Param dependent code here..
    return $.ajax({
        url:....,
        .......
    })
    .then(function (resp) {
        var retData = {};
        if(resp.length > 0){
            $.each(resp,function(key,val){
               var retObj = {};
               $.each(val,function(k,v){
                   retObj[k] = v;
               });
               retData[key] = retObj;
            });  
        }
        return retData;
   });
}

getData(x, y)
.then(function (processedResult) {
    return getData(processedResult, otherParameter);
})
.then(function (processedResult2) { 
    // use processedResult2
});
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • I understand but this gives me the raw result of the call instead of the processed one,In the getData success callback I am processing the data which I will have to process separately in each then callback – techie_28 Jan 27 '15 at 15:32
  • @techie_28 What do you mean by "the raw result"? I am 100% confident that promises will allow you to do what you need to do. If you can show me a summary of what your synchronous code looks like, I can show you what the equivalent with promises would look like. – JLRishe Jan 27 '15 at 15:35
  • Please look at the edits made in the success callback,I want the data stored in retData to be given back.I have not tried it with "then" but I did with "done" which only worked when I returned the ajax call from the function like return jQuery.ajax({....}) which gave me the raw data of the call and not the data of retData. – techie_28 Jan 27 '15 at 15:49
  • @techie_28 Please see my edit. `.then()` is the function you need to use, not `.done()`. That will allow you to chain promises together. When you have the time, please give this a read: http://bit.ly/1CK4Jdg That will get you on track with async programming in JS. And then give this a read: http://bit.ly/1Bk0sJ3 There are actually a lot of problems with jQuery promises and you should use a proper promise library like Q or bluebird. All of them have functionality to easily "wrap" a jQuery promise in one of their own promises. – JLRishe Jan 27 '15 at 16:00
  • Thanks @JLRishe that means I cant get the processed result straight out of the "success" call back of the "getData" ajax call and will have to process result separately in each ".then" which is calling it? – techie_28 Jan 28 '15 at 08:47
  • @techie_28 Yes, what I am suggesting is that you would not use the `success` callback at all. It is not needed if you are using promises. – JLRishe Jan 28 '15 at 08:49
  • Is there a way to keep the data processing part in "success" callback and get access what it is returning?Promise will only work if I return the ajax call from the function and not some other object/array containing the result? – techie_28 Jan 28 '15 at 08:54
  • @techie_28 Why do you want to keep the data processing part in the `success` callback? – JLRishe Jan 28 '15 at 09:04
  • To make that function generic so that it takes the params,makes the ajax call and gives back the result in a JS Object – techie_28 Jan 28 '15 at 09:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/69722/discussion-between-techie-28-and-jlrishe). – techie_28 Jan 28 '15 at 09:19
  • thanks @JLRishe I will be implementing this for now..Promises are the new concept for me and I will read about them but please let me know if there is a way to do it like I was expecting it. – techie_28 Jan 28 '15 at 11:18
  • @techie_28 You can pre-process the result within the `getData` function. Please see my edit. – JLRishe Jan 28 '15 at 11:54