I am calling API and loading data into table when pages gets loaded using useEffect(). but once page gets loaded user can resubmit by clicking button by using some filter.
the problem is user need to click twice then only filter is working. I am using formik to create the form and button.
const [response, setResponse] = useState([]);
const [filters,setFilters]=useState({
certificateNo:"",
protoColNo:"",
requestStatus:"",
sponser:"",
country:"",
researchTitle:"",
noOfSubjects:"",
startDate:"",
endDate:"",
})
useEffect(() => {
fetchData(page)
}, [page]);
const fetchData =async( page:any) =>{
const { certificateNo, protoColNo, requestStatus, researchTitle, sponser,country,noOfSubjects,startDate,endDate} = filters;
const param = {
...(certificateNo && { certificateNo: certificateNo }),
...(protoColNo && { protoColNo: protoColNo }),
...(requestStatus && { requestStatus: requestStatus }),
...(researchTitle && {researchTitle: researchTitle}),
...(sponser && { sponser: sponser }),
...(country && { country: country }),
...(noOfSubjects && { noOfSubjects: noOfSubjects }),
...(startDate && { startDate: startDate }),
...(endDate && { endDate: endDate }),
};
console.log('Inside fetch data');
const {data} = await axios.get(`http://localhost:3000/api/certificates?page=${page}`,{
params: param,
})
console.log("Inside data :"+data.data);
setResponse(data.data);
setFlag(true);
setLastPage(data.meta.last_page);
}
below code is calling fetchData
const handleSubmit =async (values:any)=>{
console.log("Inside the handle Submit");
setFilters(values); //Here I am setting filter value.
fetchData(page);
}
Here button is defined inside formik . what mistake I am doing?
<Formik
initialValues={formInitialSchema}
validationSchema={formValidationSchema}
onSubmit= {handleSubmit}>
<button className="btn btn-success btn-block " type="submit">
</Formik>
The issue is from your handleSubmit function. You are trying to fetch data using the filter values but you set the filter values in the form that fetches the data. The main issue is React's setState is asynchronous and the state might have not changed before fetchData(page) is called
const handleSubmit =async (values:any)=>{
console.log("Inside the handle Submit");
setFilters(values); //Here I am setting filter value.
fetchData(page);
}
You need to create your filter values the moment they are selected. This is mean making an assumption to give you a hint.
You would need to pass your filter query to fetchData in your handleSubmit and send the request rather than setting the values in the function. Example below
const handleSubmit =async (values:any)=> {
fetchData(page, values);
}
The in your fetchData function, you refactor to look like this
const fetchData = async(page:any, filters) =>{
const { certificateNo, protoColNo, requestStatus, researchTitle, sponser,country,noOfSubjects,startDate,endDate} = filters;
const param = {
...(certificateNo && { certificateNo: certificateNo }),
...(protoColNo && { protoColNo: protoColNo }),
...(requestStatus && { requestStatus: requestStatus }),
...(researchTitle && {researchTitle: researchTitle}),
...(sponser && { sponser: sponser }),
...(country && { country: country }),
...(noOfSubjects && { noOfSubjects: noOfSubjects }),
...(startDate && { startDate: startDate }),
...(endDate && { endDate: endDate }),
};
console.log('Inside fetch data');
const {data} = await axios.get(`http://localhost:3000/api/certificates?page=${page}`,{
params: param,
})
console.log("Inside data :"+data.data);
setResponse(data.data);
setFlag(true);
setLastPage(data.meta.last_page);
}