1

Why does browser.tabs.sendMessage(tab.id, connectionStatus); at the end of the code below get executed before the forEach loop above it is done?

browser.browserAction.onClicked.addListener(async tab => {

const contentScriptReady = Promise.all([
  browser.tabs.executeScript(tab.id, {file: "axios.min.js"}),
  browser.tabs.executeScript(tab.id, {file: "content.js"}),
  browser.tabs.executeScript(tab.id, { file: "sweetalert2.all.min.js" }),
  browser.tabs.insertCSS(tab.id, { file: "styles.css" })
]);

const connectionStatus = {};

var querying = browser.tabs.query({currentWindow: true, active: true});

querying.then(logTabs, onError);

function logTabs(tabs) {
  for (let tab of tabs) {
    var thisTab = tabs[0];
    var url = thisTab.url;
    var urlString = new URL(url);
    var childHSAId = urlString.searchParams.get("childhsaid");

    if (childHSAId) {
        var healthcareFacilityHSAId = urlString.searchParams.get("hsaid");
        connectionStatus.healthcareFacilityHSAId = healthcareFacilityHSAId;
        connectionStatus.childHSAId = childHSAId;

        // SE2321000057-9251 måste ändras till childHSAId
        getConnectionStatusData("SE2321000057-9251");            
    } else {

        // SE2321000057-9251 måste ändras till urlString.searchParams.get("hsaId")
        var healthcareFacilityHSAId = "SE2321000057-9251";
        connectionStatus.healthcareFacilityHSAId = healthcareFacilityHSAId;

        // SE2321000057-9251 måste ändras till healthcareFacilityHSAId
        getConnectionStatusData("SE2321000057-9251");
    }
  }
}

function onError(error) {
  console.log(`Error: ${error}`);
}

async function getConnectionStatusData(logicalAddress) {

      console.log("Det här är logicalAddress: " + logicalAddress);

  let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
      params: {
          namespace: "crm:scheduling"
      }
  });

  serviceDomainId = serviceDomains.data[0].id;

  let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
      params: {
          platform: "NTJP",
          environment: "PROD"
      }
  });

  connectionPointId = connectionPoints.data[0].id;

  var d = new Date(connectionPoints.data[0].snapshotTime);

  var options = { hour: '2-digit', minute:'2-digit' };

  var snapshotTime = d.toLocaleDateString('se-SE', options)

  connectionStatus.snapshotTime = snapshotTime;

  let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
      params: {
          logicalAdress: logicalAddress,
          serviceConsumerHSAId: "SE2321000016-92V4",
          connectionPointId: connectionPointId
      }
  });

  if (logicalAddresss.data === undefined || logicalAddresss.data.length == 0) {

          connectionStatus.errorMessage = "HSA-id " + logicalAddress + " är inte registrerat i Ineras API för Etablerad samverkan i vården. API:t uppdaterades med data från Nationella tjänsteplattformens tjänstekatalog vid " + snapshotTime + ".";

          browser.tabs.sendMessage(tab.id, connectionStatus);

          return;

  } else {

      logicalAddressId = logicalAddresss.data[0].id;

  }

  let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
      params: {
          connectionPointId: connectionPointId,
          logicalAddressId: logicalAddressId
      }
  });

  consumer = serviceConsumers.data.filter(obj => {
    return obj.hsaId === "SE2321000016-92V4";
  });

  serviceConsumerId = consumer[0].id;

  let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
      params: {
          connectionPointId: connectionPointId,
          logicalAddressId: logicalAddressId,
          serviceDomainId: serviceDomainId,
          serviceConsumerId: serviceConsumerId,
          include: "serviceContract"
      }
  });

  cooperations.data.forEach(function(cooperation) { 
    axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
      params: {
        connectionPointId,
        logicalAddressId,
        serviceDomainId,
        serviceConsumerId,
        serviceContractId: cooperation.serviceContract.id,
      },
    }).then(response => {

        serviceContract = cooperation.serviceContract.namespace.replace('urn:riv:crm:scheduling:','').replace('Responder:1','');

        connectionStatus[serviceContract] = {
          "supported": true,
          "serviceProducerDescription": response.data[0].description,
          "serviceProducerHSAId": response.data[0].hsaId
        };
    }); 
  });

  browser.tabs.sendMessage(tab.id, connectionStatus);

} /* getConnectionStatusData */

}); /* browser.browserAction.onClicked */
Rawland Hustle
  • 781
  • 1
  • 10
  • 16
  • Use `map` and `Promise.all` instead – CertainPerformance Feb 24 '19 at 08:40
  • [This](https://medium.com/front-end-weekly/3-things-you-didnt-know-about-the-foreach-loop-in-js-ff02cec465b1) compiles the problem people usually face with forEach loops. – YetAnotherBot Feb 24 '19 at 09:51
  • @CertainPerformance I hade a map function there earlier, when I was storing the response data as an array. Now I'm storing the data as individual objects. Can I use map for creating objects too? How? – Rawland Hustle Feb 24 '19 at 12:05
  • Use `map` instead of `forEach` so you have an array of Promises that you can transform into a single Promise, then call `.then` on that Promise – CertainPerformance Feb 24 '19 at 12:06
  • @CertainPerformance I've been trying to figure out how to do that but I can't get it to work. I have changed `forEach`to `map` but how do I transform it to a single promise? – Rawland Hustle Feb 24 '19 at 12:37
  • @RawlandHustle `Promise.all` – Bergi Feb 24 '19 at 13:03

0 Answers0