1

I'm using node module mongodb v3.2.7, and using express to implement my api

I use callback. And, it works well

The function findItem

const findItem = function (id, callback) {
  if (db) {
    const collection = db.collection('transaction')
    collection.find({ user_id: id})
      .project({ ready: 1, online: 1, status: 1})
      .toArray(function (err, docs) {
        if (err) {
          callback(err)
        } else {
          callback(null, docs)
        }
      })
  }
}

My api

app.get('/', (req, res) => {
  try {
    if (req.query.user_id) {
      const contentType = 'application/json'

      res.set({ 'Access-Control-Allow-Origin': '*',
        'Content-Type': contentType })

      const user_id = parseInt(req.query.user_id, 0)
      findItem(user_id , function (err, docs) {
        if (err) {
          res.status(500).end()
          return res.send(err)
        }
        const data = processData(docs)
        console.log('data', data)
        return res.send(data)
      })
    } else {
      res.send()
    }
  } catch (ex) {
    console.log(ex)
  }
})

Then, I tried to use async/await instead of callback. But, it doesn't work. What mistake I did?

Function findItemAsyncAwait

const findItemAsyncAwait = async function (id) {
  if (db) {
    const collection = db.collection('transaction')
    var docs = await collection.find({ user_id: id })
      .project({ ready: 1, online: 1, status: 1})
      .toArray()
    return docs
  }
}

My changed api

app.get('/', (req, res) => {
  try {
    if (req.query.user_id) {
      const contentType = 'application/json'

      res.set({ 'Access-Control-Allow-Origin': '*',
        'Content-Type': contentType })

      const user_id = parseInt(req.query.user_id, 0)
      const promiseDocs = findItemAsyncAwait(user_id)
      promiseDocs.then((docs) => {
        console.log('docs', docs) // <= docs [], docs is an empty array without any document
        const data = processData(docs)
        console.log('data', data)
        return res.send(data)
      }).catch((err) => {
        res.status(500).end()
        return res.send(err)
      })
    } else {
      res.send()
    }
  } catch (ex) {
    console.log(ex)
  }
})

I still got stuck on this problem. Could anyone help?

1 Answer 1

1

You have to wait the collection

const findItemAsyncAwait = async function (id) {
  if (db) {
    return await db.collection('transaction')
      .find({ user_id: id })
      .project({ ready: 1, online: 1, status: 1})
      .toArray()
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

This not only doesn't work, but also raise eslint warning Redundant use of await on a return value. The docs still is an empty array
The eslint warning is correct most of the times - it should be a direct return db.collection() and the function can be declared without async - more info here. For what concern the functionality, db.collection() used without callback should behave like a Promise.
With callback approach, it works well. So, I think there is no problem at line const collection = db.collection('transaction') and collection.find({ user_id: id})...
Try with console.log(db.collection('transaction')) - if it's a Promise you have to do const collection = await db.collection('transaction')
it's an object, not a Promise.

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.