-1

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.

demo
  • 6,038
  • 19
  • 75
  • 149
  • I think you want to call dfd.resolve() in the done handler in request3. One way to do that is to pass dfd to request2 and then to request3. Where you have the call now, the promise is resolved at the beginning of request2. – mab Nov 03 '16 at 13:52
  • Possible duplicate of [How do I chain a sequence of deferred functions in jQuery 1.8.x?](http://stackoverflow.com/questions/13651243/how-do-i-chain-a-sequence-of-deferred-functions-in-jquery-1-8-x) – Heretic Monkey Nov 03 '16 at 14:03

2 Answers2

0

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.

Andrea
  • 3,370
  • 1
  • 17
  • 25
  • Some description of what you changed and how it helps would be a good idea. – Rory McCrossan Nov 03 '16 at 13:51
  • Just adding it ;) – Andrea Nov 03 '16 at 13:54
  • your solution work for me. But what can you said about @mab comment - is it good to pass deferred as param? Thanks – demo Nov 03 '16 at 20:24
  • @demo I am glad my solution is working for you. I do not like to pass a deferred between functions. I prefer to keep the deferred in the function which creates it and change all the functions to return a promise. I think is a good practice to have all functions with async operation returning a promise, so you can chain them. – Andrea Nov 03 '16 at 23:06
0

Short answer: move vm.isLoading(true); inside the body of request3, after you call saveResponse.

Kraken
  • 5,043
  • 3
  • 25
  • 46