demo demo - 1 month ago 19
TypeScript Question

Deferred chains in jquery

I need to make 3 requests in chain. So for this I use jquery deffered.

Request 1
-> on done if response contains expected result then Request 2 else return empty array/null
-> on done if response contains expected result then Request 3 else return empty array/null





private request1() {
const vm = this;

vm.isLoading(true);
let deffer = system.defer(dfd => {dataService.getResponse1()
.done((response) => {
request2(response.collection))
dfd.resolve();
});

return deffer.promise();
}

private request2(collection) {
dataService.getResponse2(collection)
.done((response) => request3(response.collection));
}

private request3(collection) {
dataService.getResponse3(collection)
.done((response) => saveResponse(response.collection));
}

private saveResponse(collection) {
//do some stuff
}


in Constructor I call
request1
like

vm.request1().done(() => {
vm.isLoading(false);
});


The problem is that
isLoading
is setted to
false
before
saveResponse
is called. How should I correctly refactor my requests-structure to update
isLoading
after all requests are finished?

Thanks.

Answer

Try this way (please check comments in the code):

// Request 1 -> on done Request 2 -> on done -> Request 3

private request1() {
    const vm = this;

    vm.isLoading(true);
    let deffer = system.defer(dfd => {dataService.getResponse1()
       .done((response) => {
              // 1. Here you have to resolve the dfd promise after 
              // request2 promise is resolved. For this reason,
              // I added the call to "done()" method.
              request2(response.collection)).done((response2) => { dfd.resolve()});
       });

    return deffer.promise();
}

private request2(collection) {
     // 2. You need to return the promise returned by getResponse2
     return dataService.getResponse2(collection)
        .done((response) => request3(response.collection));
}

private request3(collection) {
     // 3. You need to return the promise returned by getResponse3
     return dataService.getResponse3(collection)
        .done((response) => saveResponse(response.collection));
}

private saveResponse(collection) {
    //do some stuff    
}

So, in request3() you return the promise returned by getResponse3() which, in turn, return the promise returned by saveResponse() called inside the done() method.

In request2() you return the promise returned by getResponse() which, in turn, returns the promise returned by request3() described in the previous paragraph.

In request1(), in the main done() callback, you call request2() and wait (using done()) it finishes before resolve the main promise.

In this way, vm.isLoading(false) should be called when request2 and request3 have been completed.