Reputation: 4044
The basic functionality of my app is there is a search box in homepage. The user fills the form and when submits, the user is directed to result page where the searched result will be shown along with the filtering option. Now when the user uses the filtering option and sets the price range of 10 euro minimum and 20 euro maximum, the user should see the result that is in between (10 and 20) euro instead of all the results.
What i have done is, I showed the result that user has searched. Also i have written a logic for filtering but is now blank on how to update the result with the filtered result.
logic for filtering will be like this (its just a pseudocode for showing my idea)
function carFilterFromPrice(price) {
return cars.filter(function (car) {
return car.price > price.min && car.price < price.max;
});
}
this.props.carFilterFromPrice(price);
car-result.js(parent component for result page)
class ResultLayout extends Component {
render() {
const { Origen, Destino, daterange } = this.props.carValues;
const { carResult } = this.props;
return (
<div className="container-fluid">
<CarResultFilter
origen={Origen}
destino={Destino}
daterange={daterange}
/>
<CarResult
origen={Origen}
destino={Destino}
/>
</div>
);
}
}
const mapStateToProps = state => {
console.log('state', state);
const carValues = selector(state, 'Origen', 'Destino', 'daterange');
return {
carValues,
carResult: state.getCarResult
};
};
car-result-filter.js (filtering option is simple input ranger)
class CarResultFilter extends Component {
constructor(props) {
super(props);
this.state = {
prices: { min: 0, max: 100 },
};
}
handleValuesChange(component, values1) {
this.setState({ prices });
this.props.carFilterFromPrice(this.state.prices);
}
render() {
const { origen, daterange } = this.props;
return (
<div className="car-result-filter">
<div className="container-fluid">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-3">
<InputRange
maxValue={100}
minValue={0}
value={this.state.prices}
onChange={this.handleValuesChange.bind(this)}
/>
</div>
</div>
</div>
</div>
);
}
}
car-result.js (this i want to update when filtered)
function renderCarList(cars, cityOrigen, cityDestino) {
if (cars.length > 0) {
return _.map(cars, (car) => (
<CarResultList
key={car.provider_id}
car={car}
cityOrigen={cityOrigen}
cityDestino={cityDestino}
/>
));
}
return <p> No Car to show </p>;
}
const CarResultList = ({ car, cityOrigen, cityDestino }) =>
<div className="car-result-list">
<Row className="show-grid" style={{ marginTop: 10, marginBottom: 10 }}>
<Col xs={12} sm={12} md={6}>
<img
src={car.photo ? car.photo : CarImage}
className="img-responsive car-img"
style={{ width: 200, height: 200 }}
alt={car.provider}
/>
</Col>
<Col xs={12} sm={12} md={6}>
<h3>{car.car}</h3>
<p className="sub">{cityOrigen}-{cityDestino}</p>
</Col>
</Row>
</div>;
class CarResult extends Component {
render() {
const { carResult, origen, destino } = this.props;
const carResultList = renderCarList(carResult.cars, cityOrigen, cityDestino);
if (!carResult.fetching) {
return (
<div>
Hemos encontrado {carResultList.length} ofertas para ti.
<div className="car-result-container">
<Grid>
{carResultList}
</Grid>
</div>
</div>
);
}
return (
<div>wait we are loading content for you....</div>
);
}
}
How can i update the result page with the new filtered values provided as CarResult component has cars values from the action(showResultofCar) of user submitting the form and fetching those value from reducer(getCarResult)?
UPDATE
const initialState = {
fetching: false,
fetched: true,
cars: [],
error: null
};
export function getCarResult(state = initialState, action) {
switch (action.type) {
case 'CAR_FETCH_START':
return { ...state, fetching: true };
case 'CAR_FETCH_SUCCESS':
return { ...state, fetched: true, fetching: false, cars: action.payload };
case 'CAR_FETCH_FAILURE':
return { ...state, error: action.payload };
default:
return state;
}
}
Upvotes: 0
Views: 72
Reputation: 10282
So your reducer must have a another action processor to give filtered result.
I'm using a global state for cars
which gets hydrated by CARS_FETCH_SUCCESS
. and it's used further to filter the cars according to price
.
Create you own action to filter say like following
function getFilteredResults(price){
return(dispatch, getState){
return dispatch(
type: "CARS_FETCH_WITH_FILTERS",
payload: price //price from container
)
}
}
Here is the sample implementation to go with
let cars = [];
const initialState = {
fetching: false,
fetched: true,
cars: [],
error: null
};
function carFilterFromPrice(price) {
return cars.filter(function (car) { //users global cars object to filter
return car.price > price.min && car.price < price.max;
});
}
export function getCarResult(state = initialState, action) {
switch (action.type) {
case 'CAR_FETCH_START':
return { ...state, fetching: true };
case 'CAR_FETCH_SUCCESS':
cars = action.payload; //storing all cars in global state to reuse them for filtering
return { ...state, fetched: true, fetching: false, cars: action.payload };
case 'CAR_FETCH_WITH_FILTERS': //you filter action
return { ...state, filtered: true, cars: carFilterFromPrice(action.payload.price) }; //send price in payload to filter
case 'CAR_FETCH_FAILURE':
return { ...state, error: action.payload };
default:
return state;
}
}
Upvotes: 1