I am new to all this. The output of my code should display a list of selected people (residents) saved in a firestore.
Because I retrieve the documents from Firestore using an async-await, and then want to filter them based on a search query, I have used Promise.all()
followed by .then()
before returning the final list, residenceDocs
.
In the below code, I use .map()
to perform a DisplayResident()
function, but this errors, saying it breaks the rule of hooks (DisplayResident()
has various hooks in it!).
If I try to move the mapping of the residenceDocs
outside the .then()
, the result tries to display before the promise resolves and I get an empty array (i.e. nothing displays).
I had a go at using a custom hook to bypass the issue, but that didn't work.
My question can be summed up as: How do I call a function containing hooks on the result of a promise?
const ResidentList = () => {
const [searchQuery, setSearchQuery] = React.useState('');
const { currentUserData } = useAuth();
const resTest = () => {
const residences = currentUserData.userDocRef.docs[0]._document.data.value.mapValue.fields.residences.arrayValue.values;
let residenceDocs = [];
let residentNames = [];
let isQueried = [];
const promise1 = Promise.resolve(
residences.map(async (residence) => {
let residenceId = residence.referenceValue.split('/').pop();
const docRef = doc(db, 'residences', residenceId);
await getDoc(docRef).then((result) => {
if (result.data().resident && result.data().resident.lastname) {
residenceDocs.push(result.data());
residentNames.push(result.data().resident.firstname + ' ' + result.data().resident.lastname);
} else {
console.log(`Missing out ${residenceId} as no registered resident is present at this address.`);
}
});
})
);
promise1.then(() => {
console.log(residenceDocs);
const dataFiltered = filterData(searchQuery, residentNames);
for (let i = 0; i < dataFiltered.length; i++) {
let tmpIndex = residentNames.findIndex((eachResidentName) => eachResidentName === dataFiltered[i]);
isQueried.push(tmpIndex);
}
return residenceDocs.map((eachResident, index) => DisplayResident(eachResident, index, isQueried));
});
};
return (
<MainCard style={cardStyle} title="Choose resident from list:">
<Grid container spacing={2} paddingBottom={2}>
<Grid item lg={10} xs={7}>
<SearchBar searchQuery={searchQuery} setSearchQuery={setSearchQuery} />
</Grid>
</Grid>
{resTest()}
</MainCard>
);
};