Reputation: 55
i'm having hard time figure out this. Have component which is search filter and pushes all selected filters into url. Everything works like it should except in case of refresh, in that case reducer is updated for selected filter with array with single item in which i have all selected items, not spreaded into array.
f.e. i have url
myexampleapp.com/alltrips?tripType=short_walk,cycling,downhill_cycling,long_walks&season=spring,summer,alle,vinter&lengthTo=50
my reducer
// ------------------------------------
// Constants
// ------------------------------------
export const UPDATE_FILTERS = 'UPDATE_FILTERS';
// ------------------------------------
// Actions
// ------------------------------------
const updateFilter = (key, value) => ({
type: UPDATE_FILTERS,
payload: {
key,
value
}
});
// ------------------------------------
// Action creators
// ------------------------------------
export const updateFilterState = (key, value) => {
return dispatch => {
dispatch(updateFilter(key, value));
};
};
// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
tripType: [],
season: [],
tripsTo: undefined,
tripsFrom: undefined
};
export function filterReducer (state = initialState, action) {
switch (action.type) {
case UPDATE_FILTERS: {
const key = action.payload.key;
const value = action.payload.value;
if (key === 'tripsFrom' || key === 'tripsTo') {
return Object.assign({}, state, { [key]: value });
} else {
var newFilter = state[key].slice();
var ttIdx = state[key].indexOf(value);
if (ttIdx !== -1) {
newFilter.splice(ttIdx, 1);
} else {
newFilter.push(value);
}
}
console.log(newFilter);
return Object.assign({}, state, { [key]: newFilter });
}
default:
return state;
}
}
console.log returns array with 1 element in which have array with 5 elements. but i want that 5 ekements to be in parrent array. and i'm parsing URL
componentDidMount () {
let {
location: { search },
updateFilterState
} = this.props;
search = search.slice(1);
var queries = search.split('&');
queries.forEach(q => {
var tmp = q.split('=');
if (tmp[0] && tmp[1]) {
if (tmp[0].toLowerCase() === 'triptype') {
updateFilterState(tmp[0], tmp[1].split(','));
console.log(tmp[1].split(','));
} else if (tmp[0].toLowerCase() === 'tripsto') {
updateFilterState(tmp[0], tmp[1]);
} else if (tmp[0].toLowerCase() === 'tripsfrom') {
updateFilterState(tmp[0], tmp[1]);
} else if (tmp[0].toLowerCase() === 'season') {
updateFilterState(tmp[0], tmp[1].split(','));
}
}
});
this.updateQuery(this.props);
}
So everything works except when i want to refresh.
Pretty new with all this, and been stuck for almost 3 days with this. Hope you understand what im trying to ask here as i'm pretty new and non-english speaker, so i don't know all the terms so i can better express myself. Can someone give me some pointers?
Upvotes: 0
Views: 125
Reputation: 17608
If I'm not mistaken you are feeding the reducer with an array for season
and tripType
. So, when you try to update those values, you are not actually spreading that array. This is your value
parameter. Hence, if you do this you will have a parent array with your desired result:
newFilter.push(...value);
...
is ES6's spread syntax. So we are spreading our array and pushing it into our newFilter.
But again if I don't see it wrong you will have problems with this code since you are not checking the existence of your values right. You are looking indexOf something but if you really feeding your reducer with an array, for which one you are looking this index?
Here is a cleaner way of doing this if I'm not mistaken what you are trying to do here:
export function filterReducer (state = initialState, action) {
switch (action.type) {
case UPDATE_FILTERS: {
const { key, value } = action.payload;
if (key === 'tripsFrom' || key === 'tripsTo') {
return { ...state, [key]: value };
}
const newFilter = Array.isArray(value)
? [ ...new Set( [ ...state[key], ...value ] ) ]
: [ ...new Set( [ ...state[key], value ] ) ];
return { ...state, [key]: newFilter};
}
default:
return state;
}
}
Some differences with your code:
Upvotes: 1