Search code examples
javascriptmappingeval

Javascript: Map Text to Async function


Trying to map text to async functions using eval().

function sendResponse(input) {
    var inputMap = {
        "help": "await foo1()",
        "player": "await foo2()",
        "company": "await foo3()"
    }
    return inputMap[input] || "Command not found."
}

*sometime later* 

eval(sendResponse(input));

But it breaks becuase I am calling await in eval. How can I do this successfully?

Similar to: await is only valid in async function - eval in async but I couldn't get their solution to work.

Error: UnhandledPromiseRejectionWarning: SyntaxError: await is only valid in async function

EDIT--------------------------- Here is the real code upon request:

function sendResponse(input) {
    var inputMap = {
        "help": "MOD_DISCORD['helpEmbed'].run()",
        "player": "await MOD_PLAYER['playerEmbed'].run(usr)",
        "company": "await MOD_COMPANY['companyEmbed'].run(usr)"
    }
    return inputMap[input] || "Command not found."
}

And the external method... this is await MOD_PLAYER['playerEmbed'].run(usr) (its in an external method that I export. I know that part works)

async function playerEmbed(pUsername) {
  let returnPackage = await MOD_UTIL['get'].run(`https://www.haloapi.com/profile/h5/profiles/${pUsername}/appearance`);
  let compName = "None"
  let compId = "None"
 
  if (returnPackage.Company != null) {
      compName = returnPackage.Company.Name
      compId = returnPackage.Company.Id
  }
  let embed = new DISCORD.MessageEmbed()
  .setColor('#0099ff')
  .setTitle(returnPackage.Gamertag)
  .setThumbnail(`https://www.haloapi.com/profile/h5/profiles/${pUsername}/emblem?key=${MOD_UTIL.KEY}`)
  .setImage(`https://www.haloapi.com/profile/h5/profiles/${pUsername}/spartan?key=${MOD_UTIL.KEY}`)
  .addFields(
      { name: 'Service Tag', value: returnPackage.ServiceTag},
      { name: 'Highest CSR', value: `${await getRank(pUsername)}`},
      { name: 'Company', value: compName },
      { name: 'Company ID', value: compId, inline: true  },
      { name: 'Created On', value: returnPackage.FirstModifiedUtc.ISO8601Date, inline: true },
      { name: 'Last Modified On', value: returnPackage.LastModifiedUtc.ISO8601Date, inline: true }
  )
  .setTimestamp()
  return embed
}

Solution

  • You have to change this:

    "await foo1()"
    

    To this:

    "(async () => await foo1())()"
    

    And likewise for the other foo functions. That will solve the error. However, the correct way to do what you're trying to achieve with eval is this:

    function sendResponse(input) {
      var inputMap = {
        "help": async () => MOD_DISCORD['helpEmbed'].run(),
        "player": async () => await MOD_PLAYER['playerEmbed'].run(usr),
        "company": async () => await MOD_COMPANY['companyEmbed'].run(usr)
      }
      return inputMap[input] || (async () => await "Command not found.")
    }
    
    (async () => await sendResponse(input)())();