Search code examples
javascriptasynchronousasync-awaitpromisees6-promise

How to wait on async .then


This is my code:

let curId;
if (!user) {
  db.collection("users")
    .add({
      name: name,
    })
    .then((doc) => curId = doc.id)
    .catch((err) => console.error(err));
} else {
  curId = user.id;
}
console.log(curId); <-- I need curId here

Currently I get undefined for curId because I am not waiting for the async code to finish running. What is the best way to achieve this?

Some approaches I've thought of:

  • Use await instead of .then but I feel like this may look less organized/messy with the try and catch
  • I could also add what I want to do with curId in both the if and the else statement but I'd rather not write redundant code

Solution

  • With asynchronous code you should perform actions that require waiting for a result in a .then(). With this I see a few options:

    1. Put this into a function that returns a promised value
    2. Call a function to do your logic with curId
    3. Restructure to a single promise

    Option 1

    const getCurId = (user) => {
      if (!user) {
        return db.collection("users")
          .add({ name: name })
          .then((doc) => doc.id)
      } else {
        return Promise.resolve(user.id);
      }
    };
    
    getCurId().then(curId => {
      console.log(curId); // do things with curId here
    }).catch((err) => console.error(err));
    

    Option 2

    if (!user) {
      db.collection("users")
        .add({ name: name })
        .then((doc) => doc.id)
        .then(doThingWithCurId)
        .catch((err) => console.error(err));
    } else {
      doThingWithCurId(user.id);
    }
    
    const doThingWithCurId = (curId) => {
      console.log(curId); // do things with curId here
    };
    

    Option 3

    const curIdPromise = user ? Promise.resolve(user.id) : db.collection("users")
      .add({ name: name })
      .then((doc) => doc.id);
    
    curIdPromise.then((curId) => {
      console.log(curId); // do things with curId here
    }).catch((err) => console.error(err));