I'm using redux to fetch some data using this api "https://valorant-api.com/v1/agents"
. The problem is I cannot show all the agents and only 1 showing up and I got warning from redux says:
the entity passed from selectId returned undefined, you should probably implement your own selectId function
I think there is mistake in my valorantSlice
.
I try to show the list of agents like this
(in this api I want to show the details too)
export const fetchValorants = createAsyncThunk(
"valorants/fetchValorants",
async () => {
const response = await axios
.get("https://valorant-api.com/v1/agents")
.then((response) => response.data.data)
.then((agents) => {
return Promise.all(
agents.map((agent: any) =>
axios.get(`https://valorant-api.com/v1/agents/${agent.uuid}`)
)
);
})
.then((agentDetails) => {
return agentDetails.map((response) => response.data.data);
});
return response;
}
);
Here is my slice
const valorantAdapter = createEntityAdapter();
const initialState = valorantAdapter.getInitialState({
status: "idle",
error: "" as any,
});
export const fetchValorants = createAsyncThunk(
"valorants/fetchValorants",
async () => {
const response = await axios
.get("https://valorant-api.com/v1/agents")
.then((response) => response.data.data)
.then((agents) => {
return Promise.all(
agents.map((agent: any) =>
axios.get(`https://valorant-api.com/v1/agents/${agent.uuid}`)
)
);
})
.then((agentDetails) => {
return agentDetails.map((response) => response.data.data);
});
return response;
}
);
const valorantsSlice = createSlice({
name: "valorants",
initialState,
reducers: {},
extraReducers(builder) {
builder
.addCase(fetchValorants.pending, (state, action) => {
state.status = "loading";
})
.addCase(fetchValorants.fulfilled, (state, action) => {
state.status = "succeeded";
action.payload.forEach((agent) => {
valorantAdapter.addOne(state, agent);
});
})
.addCase(fetchValorants.rejected, (state, action) => {
state.status = "failed";
state.error = action.error.message;
});
},
});
export default valorantsSlice.reducer;
export const {
selectAll: selectAllValorants,
selectById: selectValorantByUuid,
selectIds: selectValorantUuids,
} = valorantAdapter.getSelectors((state: any) => state.valorants) as any;
I use react-redux in nextjs 13
The undefined under the entity key make me think response from Valorant API don't possess any ID. (EDIT : with additional screenshot, theory seems validated :))
By default the entityAdapter of RTK will look for an id.
Based on the code of the thunk it seems that there is an uuid
instead.
https://redux-toolkit.js.org/api/createEntityAdapter#selectid
So you can pass a selectId
to createEntityAdapter
which will target the uuid
key.
const valorantAdapter = createEntityAdapter({
selectId: (valorant) => valorant.uuid,
})