What i want to do: I have a few category toggle buttons. I want to show only the data of the categories that has been checked.
My approach: The function for showing the filtered data checks the array of buttons, see which one is ticked, then reads the cache of the query.
const getFilteredData = () => {
try {
const freshFilteredData = []
for (var i = 0; i < chipData.length; i ++){
if (chipData[i].clicked){
const itineraryData = client.readQuery({
query: GET_ITINERARY,
variables: {itineraryId : chipData[i].label}
})
const wantedData = itineraryData.getItinerary.dayPlans;
freshFilteredData.push(wantedData)
}
}
setFilteredData(freshFilteredData)
} catch (err) {
console.log(err)
}
}
However, cache can only be read when a query has been fired. So I use an if-else statement to decide when to call the getFilteredData function. If the button is just checked, then I call the query (when it's completed it will call the getFilteredData function), if the button is unchecked, I call the getFilteredData directly.
const toggleClick = clickedChip => () => {
const chipClone = [...chipData];
const objectIndex = chipData.findIndex(
chip => chip.key === clickedChip.key
);
chipClone[objectIndex].clicked = !chipData[objectIndex].clicked;
setChipData(chipClone);
if (chipClone[objectIndex].clicked) {
getItinerary({variables: {itineraryId: clickedChip.label}});
} else {
console.log('fire2')
getFilteredData();
}
};
And here's my lazy query:
const [getItinerary] = useLazyQuery(GET_ITINERARY, {
onCompleted(data){
console.log('fired');
getFilteredData()
}
});
My problem: if I clicked on the same button thrice.
- click (runs query)
- unclicked (doesn't run query)
- clicked (doesn't run query, so doesn't run
getFilteredDatafunction, because query doesn't runonCompleted. And since it is clicked, it doesn't execute the 'else' statement either, sogetFilteredDatais not run at all)
That screws up the filtering.
I could get rid of the if-else statement and execute the getFilteredData function at two places:
const toggleClick = clickedChip => () => {
const chipClone = [...chipData];
const objectIndex = chipData.findIndex(
chip => chip.key === clickedChip.key
);
chipClone[objectIndex].clicked = !chipData[objectIndex].clicked;
setChipData(chipClone);
getItinerary({variables: {itineraryId: clickedChip.label}});
getFilteredData();
};
This will cover all bases, but I was wondering if there's a more elegant way to do it?