Home > Blockchain >  Async/await function is returning "undefined" instead of expected String value
Async/await function is returning "undefined" instead of expected String value

Time:09-24

I am trying to learn how to work with async functions. I have my code below. There are two functions. The first, apiAddTask, calls the second function SchedulesDAO.GetScheduleByTitle. Both functions are static async functions and 'await' is used when calling the GetScheduleByTitle function.

In the GetScheduleByTitle function, I grab the needed ID from a Mongo Database. The function is correctly grabbing the ID, but is not returning it. Instead it returns undefined.

apiAddTask function:

static async apiAddTask(req, res, next){
    try{
        let taskFrequency = null
        const taskTitle = req.body.title
        const taskRepeat = req.body.repeat 
        if (taskRepeat == true){
            taskFrequency = req.body.frequency 
        }
        const taskStart = req.body.startdate
        const taskEnd = req.body.enddate 
        let taskSchedule = await SchedulesDAO.GetScheduleByTitle(req.body.schedule) //CALL TO GETSCHEDULESBYTITLE <--

        console.log(taskSchedule) // THIS PRINTS UNDEFINED                <------------

        const addResponse = await SchedulesDAO.addTask(
            taskTitle, taskRepeat, taskFrequency, taskStart, taskEnd, taskSchedule
        )
        res.json({status:"success"})
    }catch(e){
        res.status(500).json({error: e.message})
    }
}

GetScheduleByTitle Function:

static async GetScheduleByTitle(title) {
    let query = {title: title} 
    let idString = ""
    let cursor

    try{
        cursor = await schedules.find(query)
    }catch (e) {
        console.error("Unable to issue find command: "   e)
        return {schedule: []}
    }
     
    cursor.toArray(function(err, results){
        console.log(results[0]._id.toString()) //THIS PRINTS THE RIGHT ID STRING    <-------------

        idString = results[0]._id.toString()
        return idString
    })

}

I haven't been able to figure out exactly what I am missing. Please let me know if it would be helpful to see any other code.

CodePudding user response:

Most of your code is fine. The issue lies in the fact that you are using a callback within your GetScheduleByTitle function:

async function () {
    cursor.toArray(function(err, results){
        console.log(results[0]._id.toString()) //THIS PRINTS THE RIGHT ID STRING    <-------------

        idString = results[0]._id.toString()
        return idString
    })
    // implicit return undefined
}

What is happening is that your cursor.toArray() is being called, as you expect, but it is then continuing execution onto the implicit undefined return. Your function returns undefined before any of the callback logic is even processed.

The way to fix this:

try {
    const results = await cursor.toArray()
    let idString = results[0]._id.toString()
    return idString
} catch (err) {
    console.trace(err)
    throw new Error(err)
}

Use the asynchronous promise based method.

If one does not exist, you could create a wrapper for a callback only function like so:

const cursorToArray = async (cursor) => {
  return new Promise((resolve, reject) => {
    cursor.toArray(function(err, results){
      if (results)
        resolve(results)
      else
        reject(err)
    })
  })
}
  • Related