Skip to content
Advertisement

Multiple REST API calls in succession returns undefined

I’m trying to query some JIRA issues using a the jira-connector package. I’m running into issues with the data returned not being defined until after everything else is executed in my code. I’m not sure if this is some issue with concurrency, but I can’t for the life of me figure out where and how I’m messing up.

If inside the getJiraTimeEstimations function only call the getJiraTimeEstimate once it works just fine and I get access to the data to use further down in the program. It is when I’m trying to do it inside a map or foreach where I iterate over the Array.from(dataFromMaconomy.keys()) array that I seem to run into issues.

My understanding is that adding .then().catch() in the getJiraTimeEstimate function should be enough to stop it from continuing to run before all the calls are finished? Or am I misunderstanding how asynchronous calls work in Node and JS?

I’ve also tried converting it to an async getJiraTimeEstimations and adding an await infront of the search. But it doesn’t seem to work either.

I am not populating the dataFromMaconomy array as I’m debugging. Which is what I was trying to do with the log statement. The log statement just prints undefined right now. But if I only call it with a single item from the rks array then it works fine.

function getJiraTimeEstimate(taskNumber, jiraClient) {
  jiraClient.search.search({
    jql: `id = ${taskNumber}`,
  }).then((res) => res.issues[0].fields.timeoriginalestimate).catch((err) => err);
}

function getJiraTimeEstimations(dataFromMaconomy) {
  const settings = JSON.parse(fs.readFileSync(path.join(__dirname, 'konfig.json'), 'utf8'));
  const privateKeyData = fs.readFileSync(path.join(__dirname, settings.jira.consumerPrivateKeyFile), 'utf8');
  const jira = new JiraClient({
    host: settings.jira.server,
    strictSSL: false, // Error: unable to verify the first certificate
    rejectUnauthorized: false,
    oauth: {
      consumer_key: settings.jira.consumerKey,
      private_key: privateKeyData,
      token: settings.jira.accessToken,
      token_secret: settings.jira.accessTokenSecret,
    },
  });
  console.log('getting time estimations from Jira');
  const dataFromMaconomyWithJira = [];
  const rks = Array.from(dataFromMaconomy.keys());
  rks.map((rk) => console.log(getJiraTimeEstimate(rk, jira)));
  return dataFromMaconomyWithJira;
}


function generateData(){
  const dataWithJira = getJiraTimeEstimations(convertedData);
  // More functions where I use the data from getJiraTimeEstimations
  // This gets run before all of the getJiraTimeEstimations have finished getting the data.
}

Advertisement

Answer

Giving your clarification in the comment, the getJiraTimeEstimate() function does not return anything. Try:

function getJiraTimeEstimate(taskNumber, jiraClient) {
  return jiraClient.search.search({
    jql: `id = ${taskNumber}`,
  }).then((res) => res.issues[0].fields.timeoriginalestimate).catch((err) => err);
}

Also, you mentioned trying async / await but without luck. The async version of it would be:

async function getJiraTimeEstimate(taskNumber, jiraClient) {
  try {
    const res = await jiraClient.search.search({
      jql: `id = ${taskNumber}`,
    });
    return res.issues[0].fields.timeoriginalestimate;
  } catch (e) {
    return e;
  }
}
Advertisement