I'm getting this error Unhandled Rejection (TypeError): state.push is not a function while using redux thunk but while refrshing the page after error, new word is getting added to the DB.
Below is my code.
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
export const getDictionaryAsync = createAsyncThunk(
"dictionary/getDictAsync",
async () => {
let res = await fetch("https://vocabulary-app-be.herokuapp.com/dictionary");
if (res.ok) {
let dictData = await res.json();
return { dictData };
}
}
);
export const addWordtoDictAsync = createAsyncThunk(
"dictionary/addWordtoDictAsync",
async (payload) => {
let res = await fetch(
"https://vocabulary-app-be.herokuapp.com/dictionary",
{
method: "POST",
body: JSON.stringify({ word: payload.word }),
headers: {
"Content-Type": "application/json",
},
}
);
if (res.ok) {
let data = await res.json();
console.log(data);
return { data };
}
}
);
const dictionarySlice = createSlice({
name: "dictionary",
initialState: [],
reducers: {},
extraReducers: {
[getDictionaryAsync.fulfilled]: (state, action) => {
return action.payload.dictData;
},
[addWordtoDictAsync.fulfilled]: (state, action) => {
console.log(action.payload.data + "reducer");
state.push(action.payload.data);
},
},
});
export default dictionarySlice.reducer;
The issue is that the first call to get the dictionary mutates the state invariant, from array to object. The JSON response object from "https://vocabulary-app-be.herokuapp.com/dictionary"
is an object with message
and data
keys.
{
"message": "Your data is here",
"data": [ .... your dictionary data array ]
}
The getDictionaryAsync
returns an object with dictData
key.
export const getDictionaryAsync = createAsyncThunk(
"dictionary/getDictAsync",
async () => {
let res = await fetch("https://vocabulary-app-be.herokuapp.com/dictionary");
if (res.ok) {
let dictData = await res.json();
return { dictData }; // <-- returned in action payload
}
}
);
And the reducer case sets state to this payload value.
[getDictionaryAsync.fulfilled]: (state, action) => {
return action.payload.dictData;
},
Now your state is:
{
"message": "Your data is here",
"data": [ .... your dictionary data array ]
}
And can't be pushed into.
I think you just want the dictData.data
array as the payload, or just the data
property straight from a returned dictData
object.
export const getDictionaryAsync = createAsyncThunk(
"dictionary/getDictAsync",
async () => {
let res = await fetch("https://vocabulary-app-be.herokuapp.com/dictionary");
if (res.ok) {
let dictData = await res.json();
return dictData.data; // <-- returned data property as payload
}
}
);
...
[getDictionaryAsync.fulfilled]: (state, action) => {
return action.payload; // <-- return data payload as state
},