marmelab / react-admin

A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design
http://marmelab.com/react-admin
MIT License
24.89k stars 5.23k forks source link

useQuery returns error after optimistic save #6751

Closed megantaylor closed 3 months ago

megantaylor commented 2 years ago

What you were expecting:

Fetch data with useQuery from inside Edit/Create components and correctly receive data.

What happened instead:

useQuery returns an error after save: error TypeError: Cannot read properties of undefined (reading 'data').

Steps to reproduce:

I am trying to fetch data with useQuery from inside Edit/Create components. I have redirect={false} on the SaveButton so the form stays visible.

If mutationMode={"undoable"}, useQuery returns an error after save: error TypeError: Cannot read properties of undefined (reading 'data').

Related code:

I tried to reproduce this in the CodeSandbox at https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple but I keep getting this error when it tries to compile:

ERROR in ./src/polyfills.ts
Module not found: Error: Can't resolve 'proxy-polyfill/proxy.min.js' in '/sandbox/src'
 @ ./src/polyfills.ts 5:0-38
 @ multi (webpack)-dev-server/client?http://127.0.0.1:8080 (webpack)/hot/dev-server.js ./src/polyfills.ts

I have reproduced this behavior in the react-admin demo app (pulled the repo and ran the demo locally) by changing src/reviews/ReviewEditToolbar.tsx like so:

import * as React from 'react';
import { Fragment } from 'react';
import MuiToolbar from '@material-ui/core/Toolbar';
import { makeStyles } from '@material-ui/core/styles';

import { SaveButton, DeleteButton, ToolbarProps } from 'react-admin';
import AcceptButton from './AcceptButton';
import RejectButton from './RejectButton';
import { Review } from '../types';
import { useQuery } from 'ra-core';

const useStyles = makeStyles(theme => ({
    root: {
        backgroundColor: theme.palette.background.paper,
        display: 'flex',
        justifyContent: 'space-between',
    },
}));

const ReviewEditToolbar = (props: ToolbarProps<Review>) => {
    const {
        basePath,
        handleSubmitWithRedirect,
        invalid,
        record,
        resource,
        saving,
    } = props;
    const classes = useStyles();

    const { data, loading, error } = useQuery({
        type: 'getMany',
        resource: 'categories',
        payload: { ids: [0] },
    });

    console.log('loading', loading);
    console.log('data', data);
    console.log('error', error);

    if (!record) return null;
    return (
        <MuiToolbar className={classes.root}>
            {record.status === 'pending' ? (
                <Fragment>
                    <AcceptButton record={record} />
                    <RejectButton record={record} />
                </Fragment>
            ) : (
                <Fragment>
                    <SaveButton
                        handleSubmitWithRedirect={handleSubmitWithRedirect}
                        invalid={invalid}
                        saving={saving}
                        redirect={false}
                        submitOnEnter={true}
                    />
                    <DeleteButton
                        basePath={basePath}
                        record={record}
                        resource={resource}
                    />
                </Fragment>
            )}
        </MuiToolbar>
    );
};

export default ReviewEditToolbar;
djhi commented 2 years ago

Can you elaborate on your usecase? What are you trying to achieve? I tried the code you put in the demo without having any issue. And please, follow the issue template

megantaylor commented 2 years ago

I've updated my issue to follow the issue template.

I tried to reproduce this in the CodeSandbox at https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple but I keep getting this error when it tries to compile:

ERROR in ./src/polyfills.ts Module not found: Error: Can't resolve 'proxy-polyfill/proxy.min.js' in '/sandbox/src' @ ./src/polyfills.ts 5:0-38 @ multi (webpack)-dev-server/client?http://127.0.0.1:8080 (webpack)/hot/dev-server.js ./src/polyfills.ts

I am able to reproduce the issue by running the demo from the repo locally. The error is visible in the browser devtools console.

jasonlimantoro commented 2 years ago

also experienced this issue.

Error happens here on line 134

image

I believe the variable _a is undefined for some reason. However, no network request fails.

Also, the issue only happens after the save. If you refresh the page, either through react-admin's refresh button or browser refresh, useQuery works fine.

megantaylor commented 2 years ago

I made a codesandbox fork here: https://codesandbox.io/s/keen-snowflake-tmftd

The changes I made are in src/posts/PostEdit.tsx

To reproduce the error:

  1. Click on a Post to go to Post Edit view
  2. Make some change, click save
  3. Wait for save to complete
  4. Look in the console, you will see: error TypeError: Cannot read properties of undefined (reading 'data')
megantaylor commented 2 years ago

any progress on this issue?

JustMonk commented 2 years ago

same issue, but i used dataProviderProxy from useDataProvider hook (useQuery works the same, calling useDataProvider too)

usecase: my api entity has multiple relationships and complex formatting logic on userside. I need to fetch some data (in my List or Datagrid component) for processing this in FunctionField. Yeah i know about ReferenceField but it doesn't suit me because api return nested data structures with many-to-many relationships.

another example in codesandbox: https://codesandbox.io/s/usedataprovider-example-jb68p-jb68p step to reproduce same as @megantaylor say

  1. for simplicity list has "fetched value" col and succesfuly show fetched data image

  2. Click on any row for open edit form

  3. Edit text field value and press save button

  4. After redirect we have re-mount list and dataProvider.getList return undefined image

some notes: as already mentioned, the problem lies in the mutationMode: 'optimistic' | 'undoable' if you push REFRESH_VIEW action, data will show as expected image

workaround:

fzaninotto commented 2 years ago

Reproduced, thanks for the codesandbox.

jakedeg commented 2 years ago

Hi! Just wanted to check in on this. Is it fixed as part of v4? If not, any plan on addressing it soon?

fzaninotto commented 2 years ago

We no longer export a useQuery in v4, so I supposed it's fixed

fzaninotto commented 3 months ago

With the release of react-admin v5, react-admin v3 has reached its end of life. We won't fix bugs or make any new release on the 3.x branch. We recommend that you switch to a more recent version of react-admin.

So I'm closing this issue as we won't fix it.