reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.71k stars 1.17k forks source link

RTK query error / isError / isSuccess are not updating #1803

Closed islavi closed 10 months ago

islavi commented 2 years ago

I'm trying to use error / isError to validate if the request failed, but it is always undefined.

This is my service (I set the URL to: 'non_exists_url')

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import {
  ICompanyDeleteRequest,
  ICompanyDeleteResponse
} from '../../interfaces/companies.interface'
import { RootState } from '../redux/store'

export const companyApi = createApi({
  reducerPath: 'companyApi',
  baseQuery: fetchBaseQuery({
    baseUrl: 'http://localhost:1000/v1/',
    prepareHeaders: (headers, { getState }) => {
      const token = (getState() as RootState).authReducer.token
      if (token) {
        headers.set('authorization', `Bearer ${token}`)
      }
      return headers
    },
  }),
  endpoints: (builder) => ({
    deleteCompany: builder.query<ICompanyDeleteResponse, ICompanyDeleteRequest>({
      query: ({ companyId }) => ({
        url: `non_exists_url`,
        method: 'DELETE',
        headers: {
          'X-CompanyId': companyId,
        },
      }),
    })
  }),
})

export const { useDeleteCompanyQuery } = companyApi

And this is inside the component:

import styles from './deleteCompany.module.scss'
import { FC, useEffect, useState } from 'react'

export const DeleteCompany: FC = () => {

  const companyId = 1
  const { data, error, isError } = useDeleteCompanyQuery(companyId)

  useEffect(() => {
    console.log('data', data)
    console.log('error', error)
    console.log('isError ', isError )
  }, [data, error, isError ])

  return (
    <div>
      Some text
    </div>
  )
}

In developer tools network I see 404 error But in the console isError and error are undefined

Any idea what I'm missing ?

phryneas commented 2 years ago

What do you get if you log that full result?

  const result = useDeleteCompanyQuery(companyId)

  useEffect(() => {
    console.log({result})
  }, [ result ])

Also what does it look like in the Redux Devtools? Any state changes?

islavi commented 2 years ago

This is from react dev tools: status(pin):'pending' => 'rejected' error(pin):{status:'PARSING_ERROR',origin ...

When checking with the result, I see 3 times printed to console:

  1. uninitialized
  2. pending
  3. uninitialized
phryneas commented 2 years ago

Please share the full result you are getting back, not only the status.

Generally it should be impossible for a query to fall back to uninitialized. What version of RTK are you using?

islavi commented 2 years ago

I found out that I used query instead mutation for the delete operation. Query is expecting to get JSON / text / or callback function as response, but error 404 return HTML that can not be parsed as JSON.

I ended up changing to mutation like this:

In the service file:

deleteCompany: builder.mutation<ICompanyDeleteResponse, ICompanyDeleteRequest>({ query: ({ companyId }) => ({ url: PreventDelete/companies, method: 'DELETE', }), }) Using it in component:

const [deleteCompany, { data, error, isLoading }] = useDeleteCompanyMutation()

useEffect(() => { console.log('data', data) console.log('error', error) console.log('isLoading', isLoading) if (!error && data) { NotificationManager.success('Deleting company success', Company ${company.id} deleted successfully) } else if (error) { NotificationManager.error('Delete company error', Error deleting company ${company.id}, details: ${data}) } }, [data, error, isLoading])

phryneas commented 2 years ago

Yes, things that mutate something on the server should be mutations. I'm still irritated at the behaviour you were showing here though. Were you mounting and unmounting that Delete component or something like that?

islavi commented 2 years ago

Actually the delete component was inside a modal, so yes