Reacting
Reacting

Reputation: 6123

How can I get a new array of data based on a search param?

I have some data I request from an API call which I will need to filter.

I am working on it with Redux and not local state.

Here are my actions:

import ActionTypes from '../constants/ActionTypes';


export const passengersDataAction = passengersData => ({
  type: ActionTypes.PASSENGERS_DATA,
  // This is the array of objects that I need to search through
  payload: { passengersData }, 
});

export const searchParamAction = searchParam => ({
  type: ActionTypes.SEARCH_PARAM,
  // This is the param that I need to send to passengersData
  // in order to get a new array of objects
  payload: { searchParam },
});

This is my reducer:

import createReducer from '../../../redux/createReducer';
import ActionTypes from '../constants/ActionTypes';

const initialState = {
  passengersData: [],
  searchParam: '',
};

const handlers = {
  [ActionTypes.PASSENGERS_DATA](state, action) {
    return {
      ...state,
      passengersData: action.payload.passengersData,
    };
  },

  [ActionTypes.SEARCH_PARAM](state, action) {
    return {
      ...state,
      searchParam: action.payload.searchParam,
    };
  },
};

export default createReducer(initialState, handlers);

And the above is the reducer.

What I want is to return a new array of objects based on the value of searchParam.

Something like this:

  [ActionTypes.SEARCH_PARAM](state, action) {
    return {
      ...state,
      passengersData://HERE GOES THE NEW ARRAY BASED ON WHAT searchParam RETURNS,
      searchParam: action.payload.searchParam,
    };
  },

In the component I am doing this:

  <View>
    <TextInput
      style={PassengersStyles.SearchBox}
      // searchParamActionHandler sends the input value to the update the reducer
      onChangeText={text => searchParamActionHandler(text)}
      value={searchParam}
      placeholder="Search..."
    />
  </View>
  <Text>{searchParam}</Text>
  <PassengerCardBasedOnRoute searchParam={searchParam} />

PassengerCardBasedOnRoute is the component rendering the array of objects coming from passengersData. Like this:

           {passengersData.map(info => (
            <PassengersInfo
              key={info.id}
              searchParam={this.props.searchParam}
              cardinalpoint={info.cardinalpoint}
              name={info.name}
              address={info.address}
              datetime={info.timestamp}
            />
           }

Btw this is how the array of objects looks:

[
 {
  "id": 3,
  "name": "Marcos Alonso",
  "address": "Sabana",
  "phone": "712321222",
  "pickup": 0,
  "cardinalpoint": "N",
  "latitude": "9.93683450",
  "longitude": "-84.10991830",
  "timestamp": "2019-02-19 21:23:46",
  "dropofftimestamp": null,
  "pickuptimestamp": null,
  "deleted": null,
  "driver": 1
 },
 ...
]

So, how can I return that new array to render the search criteria?

Upvotes: 0

Views: 88

Answers (2)

Hitesh Chaudhari
Hitesh Chaudhari

Reputation: 715

In the reducer for 'SEARCH_PARAM' action type, you can create a copy of the 'passengersData' from the state and mutate that copy as you want.

const initialState = {
  passengersData: [],
  searchParam: '',
  searchedData: []
};

[ActionTypes.SEARCH_PARAM](state, action) {
//In filter you can add your own logic to get the data
const searchedData = state.passengersData.filter((passenger) => passenger.name === action.payload.searchParam);

   return {
     ...state,
     searchedData,
     searchParam: action.payload.searchParam,
   };
},

FYI, this will replace the 'passesngerData' with 'searchedData'. If you want to keep the original 'passengerData' then you can create a new state in redux store and return it from the reducer.

Upvotes: 1

Hsaido
Hsaido

Reputation: 125

Updated:

if i understand well your need, you should just do that: i make a little change to map just the data that was filtred by name|address

{
    passengersData.filter(item => item['name'] === this.props.searchParam || item['address'] === this.props.searchParam).map(info => (
        <PassengersInfo
          key={info.id}
          searchParam={this.props.searchParam}
          cardinalpoint={info.cardinalpoint}
          name={info.name}
          address={info.address}
          datetime={info.timestamp}
        />
 }

you don't need to change your state BUT if you want to do that using redux you can add a new state (passengersDataFiltred for example) and do your treatment:

...
const initialState = {
   passengersData: [],
   passengersDataFiltred: [],
   searchParam: '',
};
...
[ActionTypes.SEARCH_PARAM](state, action) {
    const filtrededData = state.passengersData.filter(item => item['name'] === action.payload.searchParam || item['address'] === action.payload.searchParam);
    return {
        ...state,
        passengersDataFiltred: filtrededData,
        searchParam: action.payload.searchParam,
    };
}
...

then map the passengersDataFiltred:

      {passengersDataFiltred.map(info => (
        <PassengersInfo
          key={info.id}
          searchParam={this.props.searchParam}
          cardinalpoint={info.cardinalpoint}
          name={info.name}
          address={info.address}
          datetime={info.timestamp}
        />
       }

Please give me your feedback if that is not what you are looking for ?

Upvotes: 0

Related Questions