Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useQuery returns error after optimistic save #6751

Closed
megantaylor opened this issue Nov 5, 2021 · 10 comments
Closed

useQuery returns error after optimistic save #6751

megantaylor opened this issue Nov 5, 2021 · 10 comments
Labels

Comments

@megantaylor
Copy link
Contributor

megantaylor commented Nov 5, 2021

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
Copy link
Collaborator

djhi commented Nov 9, 2021

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
Copy link
Contributor Author

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
Copy link

jasonlimantoro commented Nov 18, 2021

also experienced this issue.

  • redirect={false} on a <SimpleForm /> component (rendered by <Edit />)
  • useQuery returns the error

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
Copy link
Contributor Author

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
Copy link
Contributor Author

any progress on this issue?

@JustMonk
Copy link

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:

  • instead of useQuery and useDataProvider hooks you can call pure dataProvider object methods
    const dataProvider = useContext(DataProviderContext); (from docs)
  • specialized hooks (useGetList, useUpdate, etc) works fine too
  • disable optimistic mode by pass prop to Create/Edit components <Edit mutationMode="pessimistic" {...props}>

@fzaninotto
Copy link
Member

Reproduced, thanks for the codesandbox.

@jakedeg
Copy link

jakedeg commented Jun 24, 2022

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

@fzaninotto
Copy link
Member

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

@fzaninotto fzaninotto added the v3 label Jun 27, 2022
@fzaninotto
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants