Search code examples
reactjsredux-thunkredux-toolkit

How update the component when the createAsyncThunk return a promise (react/redux toolkit)


I have i async function that send a request to the database to update a count, and this function return a promise like that

{Nome: "a", Valor: 1700, Historico: "teste", Documento: 1, DataEmissao: "2020-12-24T00:00:00.000Z", …}
DataEmissao: "2020-12-24T00:00:00.000Z"
DataVencimento: "2020-12-24T00:00:00.000Z"
Documento: 1
Historico: "teste"
Nome: "a"
Valor: 1700
createdAt: "2021-03-30T14:13:31.404Z"
id: "6063320bafd21c22e45f404c"
updatedAt: "2021-03-31T14:56:43.873Z"
__v: 0
__proto__: Object

this is my data updated, but i don't know how i can send this data to overwhite the old data in my component and store, my component just update when i reload de page and my app send request again to load the database data, i tried to use createEntytyAdapter but i could not.

This is my code

export const editCount = createAsyncThunk('contas/editCount', async (data) => {
    const dados = data;
    axios.post('http://localhost:8080/api/teste/' + dados.documento, {

        Documento: dados.documento,
        Nome: dados.nome,
        Valor: dados.valor,
        Historico: dados.historico,
        DataEmissao: dados.dataEmissao,
        DataVencimento: dados.dataVencimento

    }).then(function (response) {
        console.log('teste', response.data)
        return response.data;
    }).catch(function (error) {
        console.log(error)
    })
})
const ContasReducer = createSlice({
    name: sliceName,
    initialState: {
        contas: [],
        status: null
    },
    reducers: {

    },
    extraReducers: (builder) => {
        
       builder.addCase(fetchCounts.fulfilled , (state, { payload }) => {
            state.contas = payload
            state.status = 'success'
        })
        builder.addCase(fetchCounts.pending , (state, action) => {
            state. status = 'Loading'
            state. contas = [{}]
        })
        builder.addCase(createAcount.fulfilled , (state, action) => {
            state = action.payload
            console.log('action payload', action.payload)
        })
        // this is my reducer
        builder.addCase(editCount.fulfilled , (state, action) => {
            state.conta = action.meta.arg;
            console.log('reducer',action.meta.arg)
        })

    }
})

//My component 
 function SalvarDados() {
        
        Dispatch(
            editCount({
                documento: Documento,
                nome: Nome,
                valor: Valor,
                historico: Historico,
                dataEmissao: new Date(DataEmissao),
                dataVencimento: new Date(DataVencimento),
            })
        )
        props.CloseModal()
    }

@solved My function async that call the api was not returned the promise because the .then was not in front the axios.post, my code fixed

export const editCount = createAsyncThunk('contas/editCount', async (data) => {
    const dados = data;
    const response = await axios.post('http://localhost:8080/api/teste/' + dados.documento, {

        Documento: dados.documento,
        Nome: dados.nome,
        Valor: dados.valor,
        Historico: dados.historico,
        DataEmissao: dados.dataEmissao,
        DataVencimento: dados.dataVencimento

    })
    return response.data;
})
//My extra reducer
builder.addCase(editCount.fulfilled , (state, {payload}) => {
            const [data] = payload;
            const conta = state.contas.findIndex((obj) => obj.Documento === data.Documento)
            const newConta = [ ... state.contas].splice(conta, data)
            state.contas = payload;
        
        })

I hope this post can helpe someone else


Solution

  • Your createAysncThunk doesn't actually return the data. The return response.data; is the return for the .then callback function, not for the thunk itself. You need to add return in front of axios.post to return the whole promise.

    return axios.post(...)
      .then((response) => response.data);
    

    If you catch errors here then your thunk will always be fulfilled instead of rejected. It is better to let the errors be thrown. The middleware will catch them.


    This is an async function, so you can also await the Promise.

    const response = await axios.post(...);
    return response.data;