0

In the following code, why doesn't the promise inside get_dbinfo resolve prior to executing .then(result) in the calling code block?

My understanding is that the code inside the new Promise will complete before returning to the .then part of the calling statement.

    dbFuncs.get_dbinfo()
    .then((result) => {
      count = result.info.doc_count
      if (count < 500){perPage = count};
    });

    function get_dbinfo() {
      return new Promise((resolve, reject) => {
        return db.info()
        .then((result) => {
            resolve(result)
        }).catch((err) => {
            console.log(err);
            reject(err)
        });
    });
    }
Ned Studt
  • 11
  • 1
  • 1
    your second code snippet is guilty of the Promise constructor anti-pattern - i.e. you're wrapping a promise inside `new Promise` - which in 99.99999% of cases is the wrong thing to do – Bravo Nov 01 '18 at 03:45
  • 1
    `why doesn't the promise inside get_dbinfo resolve prior to executing .then` - what makes you believe it doesn't? – Bravo Nov 01 '18 at 03:46
  • 1) Because I can debug it and watch the execution bounce back to the calling function. 2) That is not an anti-pattern. It's used often in functional programming to pass a promise results to controllers. – Ned Studt Nov 01 '18 at 08:43
  • what do you have on count variable? (and in the result) – Manuel Spigolon Nov 01 '18 at 08:54
  • it is an anti-pattern because you can remove `new Promise` and get the same result - and in your self answer, you removed it – Bravo Nov 01 '18 at 11:19
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Nov 01 '18 at 12:55
  • Manuel Spigolon - the value of count is a result of db.info.doc_count. – Ned Studt Nov 02 '18 at 05:52
  • Bergi - I am not wrapping two resolves from two different promises as your reference shows. I am wrapping a single promise from a separate function in order to resolve explicit data back to the origin. There is no other means of accomplishing this task and no adverse consequences. This pattern controls program flow while providing deterministic results. – Ned Studt Nov 02 '18 at 06:02
  • Bravo: As stated in the answer, the get_dbinfo() function is unchanged from the original example Please quantify your anti-pattern statement. There is no other manner in which to pass data back to the calling function and no adverse affects. – Ned Studt Nov 02 '18 at 06:12

1 Answers1

0

Figured this out. The first issue was not returning the first call to get_dbinfo, which I did not do because it was marking the post promise parts of the function as "unreachable, due to two returns within the same function", which clued me into the second part of the issue, which was trying to include two distinct promise chains in the same function.

The final solution was to bring everything under a single promise chain with a retun on the first call to dbFuncs, as shown below. No changes were made to get_dbinfo().

    var count = 0;
      var perPage = 500;
      var page = req.query.p || 1;

    return dbFuncs.get_dbinfo()
    .then((result) => {
      count = result.doc_count
      if (count < 500){perPage = count};
    return db.find({
        selector: {
          $and: [
            {last_name: { '$gt': 1}},
          ]
        },
        use_index: ['patients'],
        sort: [{'last_name': 'asc'}],
        skip: ((perPage * page) - perPage),
        limit: perPage

      }).then((docs) => {
        let pages = Math.ceil(count / perPage);
        res.render("patients", {
          pagination: {
            currentpage: page,
            page: pages
          },
            obj: docs,
            current: page,
        });
      }).catch((err) => {
          console.log('error in patients_controller', err);
      });
    });
    };

For posterity, this complete block is an excellent way to paginate a dataset (in this case from pouchdb) to an hbs template.

Ned Studt
  • 11
  • 1