1

I'm trying to create a function in node js which reads database values in and pushes them into an array, and then at the end returns this array. My functions looks like this at the moment:

function getInvoicesCount() {
      let promiseInvoices = [];
      let userInvCount = 0;
      let deletedUserInvCount = 0;
      let userInvAmount = 0;
      let deletedUserInvAmount = 0;
      let monthWiseInvCount = [];

      db.userInvoices
        .findAll({
          attributes: [
            'deleted_at',
            [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
            [sequelize.fn('SUM', sequelize.col('invoice_amount')), 'amount'],
            [sequelize.fn('MONTH', sequelize.col('invoice_date')), 'month']
          ],
          group: ['invoice_date', 'deleted_at'],
          paranoid: false
        })
        .then(result => {
          result.forEach(function(element) {
            userInvCount += element.dataValues.count;
            userInvAmount += element.dataValues.amount;
            if (element.dataValues.deleted_at != null) {
              deletedUserInvAmount += element.dataValues.amount;
              deletedUserInvCount += element.dataValues.count;
            }
            monthWiseInvCount.push(element.dataValues);
          });
          if (monthWiseInvCount.map(a => a === 'deleted_at')) {
            monthWiseInvCount.map(a => delete a.deleted_at);
          }
          promiseInvoices.push(
            userInvCount,
            userInvAmount,
            deletedUserInvCount,
            deletedUserInvAmount,
            monthWiseInvCount
          );
        });
      return promiseInvoices;
    }

In the main part of the code I would like to call this funtion and use a .then to get the returned array

Can you help me out how I can return a promise in the function and how will the array be accessible in the .then part?

0

4 Answers 4

1

Here are the changes you need to do to get expected result :

function getInvoicesCount() {
    ...
    return  db.userInvoices.findAll({ //<-------- 1. First add return here
        ...
    }).then(result => {
        ...
        return promiseInvoices; //<----------- 2. Put this line inside the then
    });
    // return promiseInvoices; //<----------- Remove this line from here    
}

getInvoicesCount().then(data => {
    console.log(data); // <------- Check the output here
})

Explanation for this :

To get .then when you can function , function should return promise , but in you case you are just returning a blank array ,

As per the sequlize doc , db.userInvoices.findAll returns the promise so all you need to do is add return before the this function , First step is done

You were return promiseInvoices; at wrong place , why ? , coz at that you will never get the result , as the code above it run in async manner as it is promise , so you will always get the balnk array , to get the expected result you should return it from db.userInvoices.findAll's then function as shown above in code

Sign up to request clarification or add additional context in comments.

1 Comment

@JonathanLonowski , Done , Please have a look
0

You should return the results from then to access it in the chain.

function getInvoicesCount() {
  const promiseInvoices = []
  let userInvCount = 0
  let deletedUserInvCount = 0
  let userInvAmount = 0
  let deletedUserInvAmount = 0
  const monthWiseInvCount = []

  return db.userInvoices
    .findAll({
      attributes: [
        'deleted_at',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.col('invoice_amount')), 'amount'],
        [sequelize.fn('MONTH', sequelize.col('invoice_date')), 'month'],
      ],
      group: ['invoice_date', 'deleted_at'],
      paranoid: false,
    })
    .then((result) => {
      result.forEach((element) => {
        userInvCount += element.dataValues.count
        userInvAmount += element.dataValues.amount
        if (element.dataValues.deleted_at != null) {
          deletedUserInvAmount += element.dataValues.amount
          deletedUserInvCount += element.dataValues.count
        }
        monthWiseInvCount.push(element.dataValues)
      })
      if (monthWiseInvCount.map(a => a === 'deleted_at')) {
        monthWiseInvCount.map(a => delete a.deleted_at)
      }
      return promiseInvoices.push(
        userInvCount,
        userInvAmount,
        deletedUserInvCount,
        deletedUserInvAmount,
        monthWiseInvCount,
      )
    })
}

You can now use

getInvoicesCount().then(() => {
  //do something here
})

Comments

0
getData(htmlData,tags)
.then(function(data) { 
     console.log(data); //use data after async call finished
})
.catch(function(e) {
    console.log(e);
});

function getData() {
  return new Promise(function(resolve, reject) {
    //call async task and pass the response
    resolve(resp); 
  });
}

Comments

0

In general you can return a promise like this:

function returnPromise() {
    return new Promise((resolve, reject) => {
        resolve({foo: 'bar'});
    });
}

So while the other answer is completely correct, you can use the above structure to create a function that returns a promise like this:

function getInvoicesCount() {
  return new Promise((resolve, reject) => {
    let promiseInvoices = [];
    let userInvCount = 0;
    let deletedUserInvCount = 0;
    let userInvAmount = 0;
    let deletedUserInvAmount = 0;
    let monthWiseInvCount = [];

  db.userInvoices
    .findAll({
      attributes: [
        'deleted_at',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.col('invoice_amount')), 'amount'],
        [sequelize.fn('MONTH', sequelize.col('invoice_date')), 'month']
      ],
      group: ['invoice_date', 'deleted_at'],
      paranoid: false
    })
    .then(result => {
      result.forEach(function(element) {
        userInvCount += element.dataValues.count;
        userInvAmount += element.dataValues.amount;
        if (element.dataValues.deleted_at != null) {
          deletedUserInvAmount += element.dataValues.amount;
          deletedUserInvCount += element.dataValues.count;
        }
        monthWiseInvCount.push(element.dataValues);
      });
      if (monthWiseInvCount.map(a => a === 'deleted_at')) {
        monthWiseInvCount.map(a => delete a.deleted_at);
      }
      promiseInvoices.push(
        userInvCount,
        userInvAmount,
        deletedUserInvCount,
        deletedUserInvAmount,
        monthWiseInvCount
      );
      resolve(promiseInvoices); // When you are done, you resolve
    })
    .catch(err => reject(err)); // If you hit an error - reject
});
}

However that is a rather big function, would recommend splitting it up in smaller parts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.