0

I want to return a value and store it in a variable. I don't know this can be possible or not but I tried to so

let demo = await Promise.all(
                    Shop.findAll({
                      where: {
                        product_id: child.id,
                      },
                      attributes: ["id", "address"],
                    })
                      .then((adds) => {
                        adds.map(async function (add) {
                          let path = add.address;
                          return path;
                        });
                      })
                      .catch(function (err) {
                        reject(err);
                      })
                  );
                  console.log(demo);

All I am getting is demo = []

  • As my expected ouput from demo is
New York
London
Mumbai
Sydney
  • And in reality I am getting demo= []

What I am trying to do is that I need the address of the shop in the parent function as Shop is my child function so my actual code looks like this

Owner.findAll({
            raw: true,
            where: {
              id: owner.id,
            },
            attributes: ["id", "name", "address"],
          })
            .then(async (children) => {

              await Promise.all(
                children.map(async function (child) {
                 let ownerName = child.name;
                 
                  let demo = await Promise.all(
                    Shop.findAll({
                      where: {
                        product_id: child.id,
                      },
                      attributes: ["id", "address"],
                    })
                      .then((adds) => {
                        adds.map(async function (add) {
                          let path = add.address;
                          return path;
                        });
                      })
                      .catch(function (err) {
                        reject(err);
                      })
                  );
                 // I want to use demo in getStatus function
                  await getStatus(ownerName,demo);
                })
              );
            })
            .catch(function (err) {
              reject(err);
            });

I want to use shop data in my owner data

Aakash
  • 139
  • 1
  • 3
  • 22
  • `.catch(function (err) { reject(err); })` reminds me of the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)? – Bergi Jun 01 '21 at 08:03
  • Yes @Bergi its a promise constructor – Aakash Jun 01 '21 at 09:04

1 Answers1

1

There are a set of errors in the script:

  • missing return: Promise.all is not receiving any promise array
  • there are unnecessary async/await wrapping that adds overhead to the code
  • there is an async function that is sync actually let path = add.address;
  • Mixing async/await with then/catch chaining makes the code hard to read and understand
  • catch and reject multiple times

You can write it like this:

let demo = await Shop.findAll({
  where: { product_id: child.id, },
  attributes: ["id", "address"],
})
  .then(adds => {
    return adds.map(toPath);
  })

function toPath(item) {
  let path = item.address;
  return path;
}

Or the second one:

return Owner.findAll({
  raw: true,
  where: {
    id: owner.id
  },
  attributes: ['id', 'name', 'address']
})
  .then((children) => {
    return Promise.all(children.map(processChild))
  })

async function processChild (child) {
  const ownerName = child.name

  const adds = await Shop.findAll({
    where: { product_id: child.id },
    attributes: ['id', 'address']
  })
  const demo = adds.map(add => add.address)

  const status = await getStatus(ownerName, demo)
  // manage the `status` or just `return getStatus(ownerName, demo)`
  return status
}

Notice about the:

.catch(function (err) {
  reject(err);
})

in the Shop.findAll code, could lead to multiple reject calls, which leads to a memory leak. Doing like the snippet I posted, chain all the promises and let you set only one catch.

Since there is a reject function, I assume you are wrapping your code in a promise:

return new Promise((resolve, reject) => {
  Owner.findAll({...})
    .then(...)
    .catch(function (err) {
      reject(err);
    })
})

This is unnecessary because you need just to return the promise returned by Owner.findAll, this code is the same:

return Owner.findAll({...})
    .then(...)
Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73