1

I have 4 await calls that I need to call in a row. What I currently have works fine but it just looks like bad code to me. Is there a better way to write this? I tried using promise-chaining, but it just looked worse as expected.

adminSchema.statics.generateUsername = async(firstName, lastName) => {
    let generatedUsername = `${firstName}.${lastName}`.toLowerCase()

    let countTracker = 0

    const Count = ((count) => {
        if (count >= 1) {
            count++
            countTracker += count
            console.log("counted")
            console.log(countTracker)
        }
    })

    await Admin.countDocuments({ username: { $regex: new RegExp(generatedUsername) } }, (err, count) => {
        console.log("admin ran")
        Count(count)
    })
    await Teacher.countDocuments({ username: { $regex: new RegExp(generatedUsername) } }, (err, count) => {
        console.log("teacher ran")
        Count(count)
    })
    await Student.countDocuments({ username: { $regex: new RegExp(generatedUsername) } }, (err, count) => {
        console.log("student ran")
        Count(count)
    })
    await Scheduler.countDocuments({ username: { $regex: new RegExp(generatedUsername) } }, (err, count) => {
        console.log("scheduler ran")
        Count(count)
    })

    if (countTracker === 0) {
        generatedUsername = `${firstName}.${lastName}`.toLowerCase()
    } else {
        generatedUsername = `${firstName}.${lastName}.${countTracker}`.toLowerCase()
    }

    console.log(countTracker)
    return generatedUsername
}
4
  • 3
    Does countDocuments really return a Promise and accept a callback? Commented Aug 10, 2019 at 10:17
  • 2
    You could start with [Admin, Teacher, Student, Scheduler], map it to an array of Promises, then use Promise.all. No duplicate code that way. Commented Aug 10, 2019 at 10:24
  • Curious: Why do u have await if you are using callbacks? Commented Aug 10, 2019 at 10:25
  • @ambianBeing That code is pretty old and while I was still heavily learning new syntaxes and MEVN so I did some mistakes. Didn't honestly notice it until you called it out now, so thanks for that :P Commented Aug 10, 2019 at 10:30

1 Answer 1

1

One approach to run multiple async calls with minimal code would be via an async for-loop:

adminSchema.statics.generateUsername = async(firstName, lastName) => {
  let generatedUsername = `${firstName}.${lastName}`.toLowerCase()

  let countTracker = 0

  const Count = ((count) => {
    if (count >= 1) {
      count++
      countTracker += count
      console.log("counted")
      console.log(countTracker)
    }
  })

  /* Merge sequence of model counts into an asynchronous for-loop */
  for(const model of [Admin, Teacher, Student, Scheduler]) {

    /* 
    Evaluate async count() function per loop iteration. This will cause
    count() on each model to be called and completed sequentailly, one-
    after-the-next during iteration of the array. Note also that the
    callback is not needed */
    const count = await model.countDocuments({
      username: {
        $regex: new RegExp(generatedUsername)
      }
    });

    console.log(`${model.name} ran`);
    Count(count);
  }

  if (countTracker === 0) {
    generatedUsername = `${firstName}.${lastName}`.toLowerCase()
  } else {
    generatedUsername = `${firstName}.${lastName}.${countTracker}`.toLowerCase()
  }

  console.log(countTracker)
  return generatedUsername
}
Sign up to request clarification or add additional context in comments.

Comments

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.