Skip to content

ReferenceInput does not fetch current value #10634

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

Open
panfiva opened this issue Apr 1, 2025 · 3 comments
Open

ReferenceInput does not fetch current value #10634

panfiva opened this issue Apr 1, 2025 · 3 comments

Comments

@panfiva
Copy link

panfiva commented Apr 1, 2025

I am writing a AutoComplete input that stores values from users table login field. The code is as follows. Everything works just fine if perPage is large enough to include all records from users table. However, if perPage is small, then I am missing the current value in the drop-down box, and value appears to be empty

<ReferenceInput
  source='owner' // reference owner field in the current table; it contains users.login value
  reference='users' // use users table as reference
  page={1}
  perPage={5}
  queryOptions={{ refetchOnWindowFocus: false, retry: false }}
>
  <AutocompleteInput
    optionValue='login' // use users.login instead of users.id
  />
</ReferenceInput>

Root-cause:
Reference input performs 2 queries from useReferenceInputController

  • useGetList to fetch possible values
  • useReference to fetch current values

The issue with useReference query is that it expects value to include id. In my example above, I am using users.login attribute instead of users.id as optionValue; as the result, the only records that are received are the records returned by useGetList and, due to pagination settings, the current value may be missing from available choices and will not be displayed.

Proposed fix

  • Add optionValue attribute to ReferenceInput which defaults to id
  • If optionValue === 'id', continue using useReference as displayed below
  • If optionValue !== 'id', fetch current selection using useGetList with filter: { [optionValue]: currentValue }
// fetch current value
const {
    referenceRecord: currentReferenceRecord,
    refetch: refetchReference,
    error: errorReference,
    isLoading: isLoadingReference,
    isFetching: isFetchingReference,
    isPending: isPendingReference,
} = useReference<RecordType>({
    id: currentValue,
    reference,
    // @ts-ignore the types of the queryOptions for the getMAny and getList are not compatible
    options: {
        enabled: currentValue != null && currentValue !== '',
        meta,
        ...otherQueryOptions,
    },
});

Another issue is that sometimes values stored in current table's owner attribute are not found in users.login table (due to data retention issues). When that happens, the drop-down box will be empty.

If a referenced value is still missing from allChoices and availableChoices, can we add { [optionValue]: currentValue } to these variables, so we can display invalid values as selected?

@djhi
Copy link
Collaborator

djhi commented Apr 4, 2025

@djhi djhi closed this as completed Apr 4, 2025
@panfiva
Copy link
Author

panfiva commented Apr 4, 2025

@djhi , I understand that I can rename the id attribute at the data provider level; however, this is not an ideal solution. My users table already has an id field that is widely used throughout the application. However, in some cases, the simplest approach is to use users.login as a foreign key instead of users.id (we have situations when data arrives from 3rd party systems and includes login instead of id)

Moreover, it appears that the React-Admin team anticipated such use cases, as the AutocompleteInput component includes an optionValue parameter.

What I’m requesting is to extend this capability to the ReferenceInput component. This would be logical since ReferenceInput and AutocompleteInput are designed to work together; however integration between these components breaks if AutocompleteInput.optionValue is used

Would it be possible to reopen the issue?

I have provided a code sandbox to demonstrate the issue:

https://codesandbox.io/p/github/marmelab/react-admin-sandbox/csb-7wk6kf/draft/nifty-blackwell?file=%2Fsrc%2Fcomments%2FCommentEdit.tsx%3A151%2C1-173%2C32

I've added 2 AutocompleteInput components, referencing authors1 and authors2 tables (see below)

when I navigate to https://7wk6kf-8080.csb.app/#/comments/2, I see that the first drop-down box does not show a value, since it was not fetched

Image

              <ReferenceInput
                source="author.name"
                reference="authors1"
                page={1}
                perPage={2}
                queryOptions={{ refetchOnWindowFocus: false, retry: false }}
              >
                <AutocompleteInput
                  optionValue="name" //
                />
              </ReferenceInput>

              <ReferenceInput
                source="author.name"
                reference="authors2"
                page={1}
                perPage={50000000}
                queryOptions={{ refetchOnWindowFocus: false, retry: false }}
              >
                <AutocompleteInput
                  optionValue="name" //
                />
              </ReferenceInput>

  authors1: [
    { id: 1, name: "Justina Hegmann" },
    { id: 2, name: "Ms. Brionna Smitham MD" },
    { id: 3, name: "Edmond Schulist" },
    { id: 4, name: "Danny Greenholt" },
    { id: 5, name: "Luciano Berge" },
    { id: 6, name: "Kiley Pouros" },
    { id: 7, name: "Annamarie Mayer" },
    { id: 8, name: "Breanna Gibson" },
    { id: 9, name: "Logan Schowalter" },
  ],
  authors2: [
    { id: 1, name: "Justina Hegmann" },
    { id: 2, name: "Ms. Brionna Smitham MD" },
    { id: 3, name: "Edmond Schulist" },
    { id: 4, name: "Danny Greenholt" },
    { id: 5, name: "Luciano Berge" },
    { id: 6, name: "Kiley Pouros" },
    { id: 7, name: "Annamarie Mayer" },
    { id: 8, name: "Breanna Gibson" },
    { id: 9, name: "Logan Schowalter" },
  ],

@slax57
Copy link
Contributor

slax57 commented Apr 7, 2025

Hi @panfiva ,
Thank you for this additional information.

The optionValue prop was introduced because AutocompleteInput can also be used on local data. But when fetching from the API, we consider it's the dataProvider's responsibility to transform the data into the format expected by React Admin.

If you need to transform the data only for a specific call, you can pass a specific meta option in the queryOptions to let the dataProvider know.

However I'll reopen the issue and mark it as a documentation enhancement, as we should probably explain that in the documentation.
Thanks for reporting the issue in any case!

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

No branches or pull requests

3 participants