0

I have an api that takes in a userId, finds the Item associated with that, then I need to find all Accounts associated with the itemId.

I keep getting [Promise <Pending>] when I console.log Any clue how to resolve this?

router.get('/:userId', auth, async (req, res) => {
  try {
    const { userId } = req.params

    const items = await Item.find({
      userId: userId
    });

    const accounts = items.map(
      async item => {
        await Account.find({
          itemId: item.itemId
        })
    })

    console.log(items)
    console.log(accounts)
    res.json(accounts);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});
Chris McGlynn
  • 53
  • 1
  • 1
  • 8
  • async functions return a promise. accounts is an array of promises. you need to use Promise.all – user120242 May 01 '20 at 00:36
  • yes, an async function always returns a promise ...and in your case, the promise will resolve to undefined since your map callback doesn't return anything – Jaromanda X May 01 '20 at 00:37
  • 1
    you may as well just do `const accounts = items.map(item => Account.find(itemId: item.itemId))` - no need for async/await, and you'll also end up with a Promise that resolves to what you intended – Jaromanda X May 01 '20 at 00:39
  • @JaromandaX I tried your solution and got `Converting circular structure to JSON --> starting at object with constructor 'NativeTopology' | property 's' -> object with constructor 'Object' | property 'sessionPool' -> object with constructor 'ServerSessionPool' --- property 'topology' closes the circle ` – Chris McGlynn May 01 '20 at 01:18
  • that's nothing to do with "my way" - that's a problem with the data not being able to be converted to JSON - as I have no idea what `Account.find` returns, you'll need to manipulate the returned data to get what you NEED from the object that is returned by that call – Jaromanda X May 01 '20 at 01:20
  • something like `const accounts = items.map(item => Account.find(itemId: item.itemId).then(result => return the part of the result you need))` – Jaromanda X May 01 '20 at 01:21
  • ahh gotcha. thank you for your time , I'll keep poking around but at least you helped get me closer to my answer. – Chris McGlynn May 01 '20 at 01:22

1 Answers1

1

async functions return Promise. accounts is an array of Promises. You need to use Promise.all. Also your map function isn't returning anything.

  router.get('/:userId', auth, async (req, res) => {
  try {
    const { userId } = req.params

    const items = await Item.find({
      userId: userId
    });

    const accounts = await Promise.all(items.map(
        item => Account.find({
          itemId: item.itemId
        })
    ))

    console.log(items)
    console.log(accounts)
    res.json(accounts);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});
user120242
  • 14,918
  • 3
  • 38
  • 52
  • 1
    `async x => { return await y(x);}` ... is better written `x => y(x)` - with the same results :p edit: which you've just done now ... lol – Jaromanda X May 01 '20 at 00:41
  • ya, caught that later. the code actually had some syntax errors in it. – user120242 May 01 '20 at 00:43
  • I tried your answer and got `Converting circular structure to JSON --> starting at object with constructor 'NativeTopology' | property 's' -> object with constructor 'Object' | property 'sessionPool' -> object with constructor 'ServerSessionPool' --- property 'topology' closes the circle ` – Chris McGlynn May 01 '20 at 01:15
  • also tried `const accounts = items.map( (item) => { return PlaidAccount.find({ itemId: item.itemId }) } )` – Chris McGlynn May 01 '20 at 01:15
  • `res.json(await Promise.all(accounts));`? – user120242 May 01 '20 at 01:59