how can i use custom groupby function for data that i get from asyncThunk I want to store in "redux store" original array that i obtain from api and then i want to change data(by using groupby function) and display it
for example, I have a function thant call api `
export const getAnimals = createAsyncThunk(
'animals/getAnimals',
async function(_, {rejectWithValue}) {
try {
const response = await fetch('http://127.0.0.1:3001/animals')
if (!response.ok) {
throw new Error('Problem');
}
const data = await response.json();
return data;
} catch (error) {
return rejectWithValue(error.message)
}
}
);
and such array from api
"animals": [
{"animal_type": "dog","name": "Jack", "id":1},
{"animal_type": "cat","name": "Kitty", "id":2},
{"animal_type": "bird","name": "Red", "id":3},
{"animal_type": "dog","name": "Tatoshka", "id":4},
{"animal_type": "dog","name": "Rasl", "id":5},
{"animal_type": "bird","name": "blue", "id":6},
{"animal_type": "cat","name": "murr", "id":7},
{"animal_type": "snake","name": "Van", "id":8},
{"animal_type": "cat","name": "kshh", "id":9},
{"animal_type": "dog","name": "Mailo", "id":10},
{"animal_type": "cat","name": "barsik", "id":11},
{"animal_type": "monkey","name": "Ika", "id":12}
]
I have a slice with extraReducer
const animalSlice = createSlice({
name: 'animals',
initialState: {
animals: [],
loading: null,
error: null,
},
extraReducers: {
[getAnimals.pending]: (state) => {
state.loading = true;
state.error = null;
},
[ggetAnimals.fulfilled]: (state, action) => {
state.loading = false;
state.animals = action.payload;
},
[getAnimals.rejected]: setError,
}
})
`
in a companent i do something like that `
const fitOptions = [];
{
Object.keys(animals).forEach(function(animal_type, index){
fitOptions.push(
<Menu.Item key={index}>
<Accordion.Title
active={activeIndex === index}
content={animal_type}
index={index}
onClick={() => accordionClick(index)}
/>
<Accordion.Content active={activeIndex === index} content={
<Form>
<Form.Group grouped>
{animals[animal_type].map((animal) =>
<Form.Checkbox label={animal.name} name='animal_id' value={animal.id} key={animal.id} />
)}
</Form.Group>
</Form>
} />
</Menu.Item>
);
})
}
`
and I have a function groupBu that I earlyer call in reducer and as a result save in store "changed" data, but now I want to store in redux store original array and do a groupBy in reselect `
const groupBy = (xs, key) => {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
`
But I have an error, because this function starts before i get a result of api call. It's seems it must by Promise object as a result of a call, but I can't find a way to use it in this proupBy function
I will be appreciative for your help
I have tryed to create reselect
`
export const selectAnimaksByFilter = createSelector(
[selectAllAnimals, selectActiveFilter],
(allAnimals, activeFilter) => {
if (!activeFilter) {
const grouped = groupBy(allAnimals, 'animal_type');
return grouped;
}
}
);
`
and get in a component as
const animals = useSelector(selectAnimaksByFilter);
I moves groupBy to component before a render and set with .slice() method
i.e.
const animals = useSelector(selectAllAnimals);
const grouped = groupBy(animals.slice(), 'animal_type');
selectAllAnimals defined in a store
export const selectAllAnimals = (state) => state.animals.animals;