Serenity
Serenity

Reputation: 4044

show filtered result in search result page

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

Answers (1)

Jyothi Babu Araja
Jyothi Babu Araja

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

Related Questions