Pawan
Pawan

Reputation: 103

How to use the response of useMutation in react-query to display data?

I am using react-query's useMutation() to POST data, I am able to successfully post the data. But, The response i am returning after successfully posting the data I want to use that response and display it in component

For this I am using state, and i am setting state inside onSuccess function in useMutation() hook, but it is giving me error Error: TypeError: Cannot read property 'tidpWarnings' of undefined at Object.onSuccess (UpdateMIDPPage.jsx:80) at mutation.js:86

Below is my code for reference

const UpdateMIDPPage = ({ open, handleClose }) => {
  const classes = useStyles()
  const [tidpFiles, setTidpFiles] = useState([])
  const [reportFile, setReportFile] = useState('')
  const [tidpWarnings, setTidpWarnings] = useState([])
  const [reportWarnings, setReportWarnings] = useState([])
  const [toggleVisibleIcon, setToggleVisibleIcon] = useState(true)

  const { mutate, data, isSuccess, isLoading, isIdle, isError } = useMutation(
    async (body) => {
      const resp = await axios.post('http://localhost:4000/api/v1/midp/update', body)
      return resp.data
    },
    {
      onSuccess: async (data) => {    
        console.log(data)
        setTidpWarnings(data.warnings1.tidpWarnings)
        setReportWarnings(data.warnings1.reportWarnings)
      },
      onError: async (error) => {
        console.log(error)
      },
    },
  )
  const handleUpdateMIDP = () => {
    const body = {
      projectId,
      tidpFiles,
      reportFile,
    }
    mutate(body)
    // also tried this doesnt work eiter
    // mutate(body, {
    //   onSuccess: async () => {
    //     setTidpWarnings(data.warnings1.tidpWarnings)
    //     setReportWarnings(data.warnings1.reportWarnings)
    //   },
    // })
  }

  return (
    <div className={classes.container}>
      <div className={classes.action}>
        <div>       
          <Button
            onClick={handleUpdateMIDP}
            className={classes.updateBtn}
            variant='contained'
            disableElevation
            startIcon={<CheckIcon />}
            disabled={tidpFiles === [] ? true : reportFile === '' ? true : isSuccess ? true : false}
          >
            {isIdle
              ? 'Generate MIDP'
              : isLoading
              ? 'Processing...'
              : isSuccess
              ? 'Processed!'
              : isError
              ? 'Error'
              : null}
          </Button>
        </div>
        <div>         
          <Tooltip title='Toggle upload section'>
            <IconButton onClick={() => setToggleVisibleIcon(!toggleVisibleIcon)}>
              {toggleVisibleIcon ? <VisibilityIcon /> : <VisibilityOffIcon />}
            </IconButton>
          </Tooltip>
        </div>
      </div>
      {toggleVisibleIcon ? (
        <UploadSection
          reportFile={reportFile}
          setReportFile={setReportFile}
          tidpFiles={tidpFiles}
          setTidpFiles={setTidpFiles}
        />
      ) : null}
      {isLoading ? <div>loading ....</div> : null}
      {isSuccess ? <WarningSection tidpWarnings={tidpWarnings} reportWarnings={reportWarnings} /> : null}
    </div>
  )
}

If i comment the setState code inside the onSuccess, everything works fine.

Here is the APi response for reference

{status: "success", data: {…}}
data:
ignoreFiles: (2) ["test1.xlsx", "test5.xlsx"]
warnings1: {tidpWarnings: Array(3), reportWarnings: Array(0)}
__proto__: Object
status: "success"
__proto__: Object

Please help me in figuring this out, thx

Upvotes: 8

Views: 15104

Answers (1)

TkDodo
TkDodo

Reputation: 28833

For this I am using state, and i am setting state inside onSuccess function in useMutation() hook

The data returned from useMutation will contain the response returned from the api, so there shouldn't be the need to add extra state management

Upvotes: 4

Related Questions