Reputation: 1668
In my React JS project.
I am listing the restaurant list to the customers. There are filters mainly the cuisine filter. Customers can select the cuisine and then data will be fetched from the API and re-rendered.
Redux Store to store the data
{
restaurants: [],
filters: {
cuisines: []
}
}
restaurants: []
will store all the restaurant's data, while cuisines: []
stores the filtered cuisine ids.
In componentWillMount()
I have the logic which fetches the restaurants from the API and stores it inside the redux store.
At the same time, it will also check for the cuisines: []
from store to get the filtered data from the API.
Here is my filters component.
import React from 'react';
import {connect} from 'react-redux';
import {setSelectedCuisine, removeSelectedCuisine} from './../../actions/filterActions';
import {setRestaurants} from './../../actions/restaurantActions';
import {fetchRestaurants} from './../../utils/ApiLibrary';
import {loadJsLibraries} from './../../utils/LoadLibrary';
class Filters extends React.Component {
lat = this.props.location.latitude;
lng = this.props.location.longitude;
maxDistance = 50;
category = 'nearby';
limit = 50;
cuisineIds = this.props.filters.cuisines || [];
restaurantAPI = '/gokhana/restaurant/categorized';
cuisineStatus = (id) => {
const cuisineFound = this.props.filters.cuisines.find((cuisineId) => {
return cuisineId === id;
});
return cuisineFound ? true: false;
}
handleCheckBoxChange = (e) => {
let isChecked = e.target.checked;
isChecked ?
this.props.setSelectedCuisine(e.target.value)
: this.props.removeSelectedCuisine(e.target.value);
fetchRestaurants(
this.restaurantAPI,
this.lat,
this.lng,
this.maxDistance,
this.category,
this.limit,
this.cuisineIds
).then(result => dispatch(this.props.setRestaurants(result)));
}
render() {
return (
<div className="col-md-3">
<div id="filters_col">
<a
data-toggle="collapse"
href="#collapseFilters"
aria-expanded="true"
aria-controls="collapseFilters"
id="filters_col_bt
">
Filters
<i className="icon-plus-1 pull-right"></i>
</a>
<div className="collapse" id="collapseFilters">
<div className="filter_type">
<h6>Distance</h6>
<input type="text" id="range" value="" name="range"/>
<input type="text" id="range-test" value="" />
<h6>Food Type</h6>
<ul>
<li><label><input type="checkbox" className="icheck" />Veg Only</label></li>
</ul>
<h6>Outlet Type</h6>
<ul>
<li><label><input type="checkbox" className="icheck" />Restaurant</label></li>
<li><label><input type="checkbox" className="icheck" />Food Court</label></li>
</ul>
</div>
<div className="filter_type">
<h6>Cuisines</h6>
<ul className="nomargin">
{
this.props.cuisines.map((cuisine) => {
return (<li>
<label className="checkbox-container">
{cuisine.name}
<input
type="checkbox"
value={cuisine.id}
className="cuisineCheckbox"
onChange={(e) => this.handleCheckBoxChange(e)}
{...this.cuisineStatus(cuisine.id) ? {checked: true} : {} }
/>
<span className="checkmark"></span>
</label>
</li>)
})
}
{loadJsLibraries()}
</ul>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = {
setSelectedCuisine,
removeSelectedCuisine,
setRestaurants
};
export default connect(state => state, mapStateToProps)(Filters);
I have multiple cuisines checkboxes, Now, when I check a checkbox then setSelectedCuisines
action is dispatched, and if I uncheck a checkbox removeSelectedCuisine
is dispatched.
This mechanism is working perfect, no problem. Now, the actual problem is.
Whenever, setSelectedCuisines
or removeSelectedCuisines
gets called, after completion of this action, I want to call the API which fetches the restaurant data based upon the filters selected.
After calling API, I also want to dispatch the action setRestaurants
which will set the restaurants in store.
In above component, you can see the handleCheckBoxChange
dispatching the setSelectedCuisines
and removeSelectedCuisines
. And at the same time I am calling a function to fetch the restaurants from the API and dispatch the setRestaurant
.
Problem here is that, the setRestaurants
action gets called immediately after cuisines action gets called and I am not getting the correctly filtered data from the API.
I am worried about this, as I am not sure where and when can I call the fetchRestaurants()
function so that I get filtered data.
Upvotes: 0
Views: 163
Reputation: 5669
I will tell you two ways to do this,
Add the logic for creating the array of selected cuisines in the handleChange() to a variable and use this value to Call the api and send the dispatch.
Use pub-sub and inside your reducer, after merging with the existing cuisines in case of checkbox selection or removing old ones otherwise, and then call the pubsub PubSub.publish() to call a function which fetches your api.
Upvotes: 1
Reputation: 1057
You can dispatch the function like below
this.props.dispatch(this.props.setRestaurants(result))
Upvotes: 0