问题
i have try to get the excel sheet using xlsx-populate so i am trying to get the values from mailEvents collections so i can add or pass the value in the init Collection function.if i have solved this issue then my problem regarding excel is also solved.
in this problem i want to access the topHeader var in init collection.
here in arr2 there is the values in this form ['open','processed']
const completeReport = (startTime,endTime) => {
serverRef = db.collection("MailEvents");
let getDocs = serverRef
.where("timestamp", ">=", startTime)
.where("timestamp", "<=", endTime)
.get()
.then(querySnapshot => {
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
let arr1 = ["email", "reportName", "office"];
let arr2 = docs.map(a => a.event);
let topHeader = [...new Set(arr1.concat(arr2))];
}
});
let query = db.collection("inits");
let queryData = query
.where("report", "in", ["payroll", "footprints"])
.get()
.then(querySnapshot => {
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
console.log(topHeader)
}
});
}
so i want the output in this form
["email", "reportName", "office",'open','processed']
回答1:
Data is loaded from Firebase asynchronously, since it may take some time to return. Instead of waiting for the data to return, your main code continues to execute straight away. Then when the data is available, your then()
callback is called with that data.
This means that any code that needs access to the data from Firestore must be inside the then()
callback, or be called from there.
For example:
const completeReport = (startTime,endTime) => {
serverRef = db.collection("MailEvents");
let getDocs = serverRef
.where("timestamp", ">=", startTime)
.where("timestamp", "<=", endTime)
.get()
.then(querySnapshot => {
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
let arr1 = ["email", "reportName", "office"];
let arr2 = docs.map(a => a.event);
let topHeader = [...new Set(arr1.concat(arr2))];
let query = db.collection("inits");
let queryData = serverRef
.where("report", "in", ["payroll", "footprints"])
.get()
.then(querySnapshot => {
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
console.log(topHeader)
}
});
}
});
}
There are some alternatives, especially when you're willing to use more modern JavaScript constructs. The simplest approach is to use the async
/ await
keywords, which wrap the above in some nice syntactic sugar that reads more normal for most developers.
The above code would become this when you apply async
/ await
:
const completeReport = async (startTime,endTime) => {
serverRef = db.collection("MailEvents");
let querySnapshot = await serverRef
.where("timestamp", ">=", startTime)
.where("timestamp", "<=", endTime)
.get();
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
let arr1 = ["email", "reportName", "office"];
let arr2 = docs.map(a => a.event);
let topHeader = [...new Set(arr1.concat(arr2))];
let query = db.collection("inits");
querySnapshot = await serverRef
.where("report", "in", ["payroll", "footprints"])
.get();
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
console.log(topHeader)
}
}
}
The biggest changes here are:
- The
async
marker on thecompleteReport
function, since the caller needs to be aware that this function may now return a promise/exhibit async behavior. - The
await
keywords on the twoget()
calls, which mean you don't need athen
block anymore. - The reduced indentation, especially when compared to the first snippet in my answer.
One of the things to always realize when using this approach is that the calls are still asynchronous. While the use of async
/ await
makes the code easier to read, it doesn't change the actual behavior of the APIs.
回答2:
Since let has block scope it wont be accessible outside.
Would recommend you to declare a variable with var
and just assign it later.
Hope this helps!
const completeReport = () => {
let serverRef = db.collection("MailEvents");
var topHeader;
let getDocs = serverRef
.where("timestamp", ">=", startTime)
.where("timestamp", "<=", endTime)
.get()
.then(querySnapshot => {
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
let arr1 = ["email", "reportName", "office"];
let arr2 = docs.map(a => a.event);
topHeader = [...new Set(arr1.concat(arr2))]; //assign value
}
});
serverRef = db.collection("inits");
let queryData = serverRef
.where("report", "in", ["payroll", "footprints"])
.get()
.then(querySnapshot => {
if (querySnapshot) {
let docs = querySnapshot.docs.map(doc => doc.data());
console.log(topHeader)
}
});
}
来源:https://stackoverflow.com/questions/59511999/scope-issue-in-javascript-between-two-functions