Skip to content
Advertisement

Undefined from promise using .then() JavaScript

I am trying to get data from Firestore using multiple queries, but the returned data is always undefined, even though console.log(data) in .then() block shows the data exist.

const getPeers = async () => {
    let query = firestore.collection("users");
    if (country !== "") query = query.where("country", "==", country);
    if (gender !== "") query = query.where("gender", "==", gender);
    if (age !== "") query = query.where("age", "==", age);
    if (religion !== "") query = query.where("religion", "==", religion);
    if (budget_low !== "") query = query.where("budget_low", ">=", Number(budget_low));
    if (budget_high !== "") query = query.where("budget_high", "<=", Number(budget_high));
    query
      .get()
      .then((querySnapshot) => {
        var data = [];
        querySnapshot.forEach((doc) => {
          data.push(doc.data());
        });
        console.log(data) // data exist here after console log.
        return data;
      })
      .catch((error) => {
        console.log("Error getting documents: ", error);
      });
  };

  let d = await getPeers();
  console.log(d); // gets undefined

Advertisement

Answer

You have to return the promise in your function getPeers():

const getPeers = async () => {
    let query = firestore.collection("users");
    if (country !== "") query = query.where("country", "==", country);
    if (gender !== "") query = query.where("gender", "==", gender);
    if (age !== "") query = query.where("age", "==", age);
    if (religion !== "") query = query.where("religion", "==", religion);
    if (budget_low !== "") query = query.where("budget_low", ">=", Number(budget_low));
    if (budget_high !== "") query = query.where("budget_high", "<=", Number(budget_high));
    return query // here return the promise
      .get()
      .then((querySnapshot) => {
        var data = [];
        querySnapshot.forEach((doc) => {
          data.push(doc.data());
        });
        console.log(data) // data exist here after console log.
        return data;
      })
      .catch((error) => {
        console.log("Error getting documents: ", error);
      });
  };

EDIT:

A little advice when handling errors in async functions, in your code you have the catch() handler with a console.log:

return query.get() // here return the promise     
      .then((querySnapshot) => {
        ...
      })
      .catch((error) => {
        console.log("Error getting documents: ", error); 
        // If query.get() fails, then 'await getPeers();'
        // will return 'undefined'. 
      });
};

let d = await getPeers();
console.log(d); // will be undefined if query.get() returns an error.
  

To avoid this you could throw an error in catch() like this:

.catch((error) => {
   throw "An error occurred";
});

So then you can check if an error ocurred like this:

let d = await getPeers().catch(error => {
  // here you can throw the error or do something else like return null for example.
 console.error(error);
 return null;
});

if (d){ // now you can validate that your data exists
...
}

You can see more about async functions here.

Remember this:

Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement