0

I have a function that returns some data based on conditions but in my else I want to call 2 functions but I want the first one to run before the second one does. I think I can add a promise here but I am not sure how to do that.

My code:

result.data.table_fields.forEach((d) => {
    if (d.type != "connected_field") {
      // do something
    } else {
      getAllTables({ query: tables(dev_id) }).then((res) => {
        if (d.label in res) {
          // do something
        } else {
            getAllTables({ query: tables(prod_org) }).then((prod) => {
               if (d.label in prod) {
                  //do something
               } else console.log(`${d.label} DOES NOT EXIST}`);
            });
        }
      });
    }
  });

Is there a way to do this without nesting the functions. I need to check if the value first exists in dev before checking prod.

nb_nb_nb
  • 1,243
  • 11
  • 36
  • 2
    `promise.then((res) => { body })` can generally be rewritten as `let res = await promise; body;` – Barmar May 01 '23 at 19:32

1 Answers1

1

Declare the function you're calling in forEach async, then you can use await inside it instead of nested .then().

result.data.table_fields.forEach(async(d) => {
  if (d.type != "connected_field") {
    // do something
  } else {
    let res = await getAllTables({query: tables(dev_id)});
    if (d.label in res) {
      // do something
    } else {
      let prod = await getAllTables({query: tables(prod_org)});
      if (d.label in prod) {
        //do something
      } else {
        console.log(`${d.label} DOES NOT EXIST}`);
      }
    }
  }
});

However, this does lots of repeated getAllTables() queries in the loop. You might want to do both of them just once, then check whether d.label is in either of the results in the loop.

(async() => {
  let dev = await getAllTables({
    query: tables(dev_id)
  });
  let prod = await getAllTables({
    query: tables(prod_org)
  });

  result.data.table_fields.forEach((d) => {
    if (d.type != "connected_field") {
      // do something
    } else if (d.label in dev) {
      // do something
    } else if (d.label in prod) {
      //do something
    } else {
      console.log(`${d.label} DOES NOT EXIST}`);
    }
  });
})();
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • …and also one should not pass an `async` function as a callback to `forEach`, so the second snippet is definitely preferable – Bergi May 01 '23 at 19:55
  • @Bergi Why should you not pass an `async` callback? I don't see a problem with it if its effects are local to the array's item, and a rejection is insignificant. – Oskar Grosser May 01 '23 at 20:55
  • 1
    @OskarGrosser [because it does not work](https://stackoverflow.com/q/37576685/1048572), and rejections are not insignificant, they crash your entire nodejs process – Bergi May 01 '23 at 23:15