0

Code explanation:

If internet is available it will sync the unsynced data from the different tables based on different methods.But, I would like to know how to add promise for these different functions.The logic which I used in making all the functions to start simultaneously but, I would like to start function2 based on the success of function1 and repeat the same process can anyone tell me how to do it.

function syncApp () {
  $log.log('offlineOnlineSync got called');

  Contact.syncApp().then(function (resp) {
    $log.log('Contact sync got called', resp);

    WorkerGroup.syncApp().then(function (resp) {
      $log.log('WorkerGroup sync got called', resp);

      Category.syncApp().then(function (resp) {
        $log.log('Category sync got called', resp);

        Vehicle.syncApp().then(function (resp) {
          $log.log('Vehicle sync got called', resp);

          Daybook.syncApp().then(function (resp) {
            $log.log('Daybook sync got called', resp);
          }, CommonService.errorHandler);

        }, CommonService.errorHandler);

      }, CommonService.errorHandler);

    }, CommonService.errorHandler);

  }, CommonService.errorHandler);
}

In the first method the process which takes place is this but before completing the above process the second method gets called.

    prom = DB.update('contacts', servResp, 'id', key)
      .then(function () {
        if (servResp.type === 'Worker') {
            WorkerGroup.checkGroupForTempIds(key, servResp.id)
             .then(function (resp) {
                  $log.log('Response in contact service', resp);
            }, function (err) {
                  $log.log('err: ', err);
            });
        } // fix me // not needed
    }, function (err) {
          $log.log('err: ', err);
    });

    $log.log('serverresponseid', servResp.id);
    $log.log('key', key);
    var daybook_updatequery = 'UPDATE daybook SET contact_id = ? WHERE contact_id = ?';

    $cordovaSQLite.execute(Database.db, daybook_updatequery, [servResp.id, key])
      .then(function (resp) {
        $log.log('response', resp);
        defer.resolve('success');
    }, function (err) {
        q.reject(err);
        $log.log(err);
    });

    proms.push(prom);
});
$q.all(proms).then(function () {
    defer.resolve('success');
});
georgeawg
  • 48,608
  • 13
  • 72
  • 95
Nidhin Kumar
  • 3,278
  • 9
  • 40
  • 72
  • Have a look at this : https://docs.angularjs.org/api/ng/service/$q – arqam Aug 02 '17 at 13:13
  • What is the problem with your example code besides being ugly? Does it work? – Tamas Hegedus Aug 02 '17 at 13:13
  • @TamasHegedus Lol. – arqam Aug 02 '17 at 13:13
  • Try to [chain your promises](http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/), or use `$q.all()` – Marlon Barcarol Aug 02 '17 at 13:17
  • @arqam OP asked "how to do it", not "how to do it better". I see a chance that there is some error in the current approach (an error in one of the called services for example) but the real problem has not been stated due to miscommunication. – Tamas Hegedus Aug 02 '17 at 13:20
  • 1
    It is difficult to tell what is wrong with the `getAllProms` function because parts of it are missing. On first observation, it fails to use [return statements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return) in the `.then` handler functions and it uses broken [$q.defer anti-patterns](https://stackoverflow.com/questions/30750207/is-this-a-deferred-antipattern). – georgeawg Aug 02 '17 at 15:30
  • Your edit is incomplete. Is `prom` a global variable? What is `defer`? What is `q`? (`q` is not the same as `$q`) – Tamas Hegedus Aug 03 '17 at 08:46

2 Answers2

2

You can chain the promises, so you only need one error handler:

function syncApp () {
  $log.log('offlineOnlineSync got called');
  return Contact.syncApp().then(function (resp) {
    $log.log('Contact sync got called', resp);
    return WorkerGroup.syncApp();
  }).then(function (resp) {
    $log.log('WorkerGroup sync got called', resp);
    return Category.syncApp();
  }).then(function (resp) {
    $log.log('Category sync got called', resp);
    return Vehicle.syncApp();
  }).then(function (resp) {
    $log.log('Vehicle sync got called', resp);
    return Daybook.syncApp();
  }).then(function (resp) {
    $log.log('Daybook sync got called', resp);
  }).catch(function(err) {
    CommonService.errorHandler(err);
  });
}
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
1

To have parent promises wait for completion of chained promises, it is important to return the chained promise to the parent .then handler function:

function getProm(servResp, key) {
    ͟r͟e͟t͟u͟r͟n͟ DB.update('contacts', servResp, 'id', key)
      .then(function () {
        if (servResp.type === 'Worker') {
            ͟r͟e͟t͟u͟r͟n͟ WorkerGroup.checkGroupForTempIds(key, servResp.id)
             .then(function (resp) {
                  $log.log('Response in contact service', resp);
                  ͟r͟e͟t͟u͟r͟n͟  resp;
            }, function (err) {
                  $log.log('err: ', err);
                  //IMPORTANT
                  throw err;
            });
        } else {
            ͟r͟e͟t͟u͟r͟n͟ "something";
        };
    }, function (err) {
          $log.log('err: ', err);
          //IMPORTANT
          throw err;
    });
}

Also to avoid converting rejected promises to fulfilled promises, it is important to use a throw statement in the rejection handler function.

When a .then method handler function omits a return statement, the method returns a new promise that resolves undefined and that promise does not wait for any asychronous operations started in that handler function.

For more information, see You're Missing the Point of Promises

georgeawg
  • 48,608
  • 13
  • 72
  • 95