Related and an almost direct extension of my earlier question
I am using useEffect to run a function that grabs data from firebase. The data is grabbed, however only the first element appears to show the additional information added to the state.
const [expenses, setExpenses] = useState([]);
const roster = [];
var db = firebase.firestore();
React.useEffect(() => {
const getRoster = async () => {
db.collection("Roster")
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
var data = doc.data();
data.ID = doc.id;
roster.push(data);
});
// setExpenses(roster);
// console.log("expenses", expenses);
// console.log("roster", roster);
})
This is working as expected, the commented out code was the solution to my previous question. I added in the code below and experienced my new issue.
.then(() => {
roster.forEach((member) => {
let total = 0;
db.collection("Attendance Entries")
.where("attendees", "array-contains", member.ID)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
total++;
member.total = total;
});
setExpenses(roster);
});
});
});
};
getRoster();
}, []);
The first element shows the "member.total" on the inital load, the others only appear after the state is changed. Not sure why that is the case..
Thank you for the help!
I don't quite follow all of your code, but I see a possible issue with the way you enqueue state updates in the forEach
loop in the section of code you say you've an issue with. When you enqueue state updates in a loop you must use a functional state update so each enqueued update doesn't blow away (overwrite) the previous state.
You can iterate the roster
array you've previously computed and then compute the docs total for each member
and mutate the member object, then use a functional state update to append the new member object to the expenses state array.
.then(() => {
roster.forEach((member, index) => {
let total = 0;
db.collection("Attendance Entries")
.where("attendees", "array-contains", member.ID)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
total++;
});
member.total = total;
setExpenses(expenses => expenses.concat(member));
});
});
});