0

I'm confused. I'm new to async so I know I'm missing something fundamental but I'm scratching my head. From the examples I've seen, I thought I had this right but...

The below code works fine when mocked. However, when I fetch the real dashboard object from mongo I can see execution is not in order. Therefore the code that relies on there being a dashboard object fails due to it being 'undefined'.

Relevant code

router.get('/:id?', (req, res) => {
  getDashboardData(req)
})

async function getDashboardData(req) {  
  const dashboardId = await getDashboardId(req)
  const dashboard = await loadDashboard(dashboardId)
  const results = await showResults(dashboardId, dashboard)
}

async function getDashboardId(req) {
  dashboardId = req.params.id.trim()
  // Some other things happen here but ultimately we return a UUID 
  return(dashboardId)
}

async function loadDashboardFromId (dashboardId) {  
  Dashboard.findOne({dashboardId: dashboardId}).then((dashboard) => {
    if (dashboard == null || dashboard.dashboardId == null) {
      throw new Error('No dashboard matched in loadDashboardFromId for dashbardId: ' + dashboardId)
    } else {
      console.log('dashboard within loadDashboardFromId: ' + dashboard)
      return dashboard
    }      
  })
}

async function showResults(dashboardId, dashboard) {
  console.log("dashboardId: " + dashboardId)
  console.log("dashboard within showResults: " + dashboard)
}

Console output below. You can see showResults() executes before loadDashboard() returns:

connected to mongo server.
open connection to mongo server.
dashboardId: dbc7e954-c6a7-490f-8d9b-4dd11f11d262
dashboard within showResults: undefined
dashboard within loadDashboardFromId: {
  _id: new ObjectId("6208f552a442468c65987e62"),
  dashboardId: 'dbc7e954-c6a7-490f-8d9b-4dd11f11d262',
  createdDate: 2022-02-13T00:00:00.000Z,
  surveyId: 'b55a58d6-63f1-473e-9a3c-34f5d63af499',
  participantId: '9b274cfe-68ea-4206-9f3c-f2ee309ec4de',
  personalityTotal: new Decimal128("69"),
 // etc }```

2 Answers 2

2

Don't mix up then/catch and await. Use either one or another. I'd prefer await:

async function loadDashboardFromId (dashboardId) {  
  const dashboard = await Dashboard.findOne({dashboardId: dashboardId})
  if (dashboard == null || dashboard.dashboardId == null) {
    throw new Error('No dashboard matched in loadDashboardFromId for dashbardId: ' + dashboardId)
  } else {
    console.log('dashboard within loadDashboardFromId: ' + dashboard)
    return dashboard
  }      
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is making more sense now. Thanks @Anatoly. Any idea why I'm getting a comma moan? The 'const await dashboard = ' line has a comment " ',' expected".
Seems in Node I needed a small tweak and everything is now working as planned. Appreciated. Change in syntax was: const dashboard = await Dashboard.findOne({dashboardId: dashboardId})
My bad. Misplaced await. I updated my answer
0

You can use Promise ... For More Documentation https://www.newline.co/fullstack-react/30-days-of-react/day-15/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve

  async function getDashboardData(req) { 
    var dashboardId;
    var dashboard;
    var promise = new Promise(async function(resolve, reject) {
      dashboardId = await getDashboardId(req)
      dashboard = await loadDashboard(dashboardId)
      if(dashboardId && dashboard){
         resolve(true);
       }
      })
    const results = await showResults(dashboardId, dashboard)
   }

3 Comments

I see, thanks. I got a syntax error warning as below. Any ideas? dashboardId = await getDashboardId(req) ^^^^^ SyntaxError: await is only valid in async functions and the top level bodies of modules
Oh i mistook it. I edited the code. new Promise(async function(resolve, reject) Here you use async. If you got error , Please comment here.
Oh, my! Why use new Promise inside async functions around two async function calls with await? Totally an overkill! They ARE already async and awaited there.

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.