diff --git a/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx b/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx
index e0d2af252a2..6f2175fab34 100644
--- a/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx
+++ b/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx
@@ -7,6 +7,138 @@ import renderWithRedux from '../../util/renderWithRedux';
describe('', () => {
it('should set loaded to false when related records are not yet fetched', async () => {
+ const ComponentToTest = ({ loaded }: { loaded?: boolean }) => {
+ return
loaded: {loaded.toString()}
;
+ };
+
+ const { queryByText } = renderWithRedux(
+
+ {props => }
+ ,
+ {
+ admin: {
+ resources: {
+ bar: {
+ data: {
+ 1: { id: 1, title: 'hello' },
+ 2: { id: 2, title: 'world' },
+ },
+ },
+ },
+ references: {
+ oneToMany: {
+ 'foo_bar@fooId_barId': {},
+ },
+ },
+ },
+ }
+ );
+
+ expect(queryByText('loaded: false')).not.toBeNull();
+ await waitFor(() => {
+ expect(queryByText('loaded: true')).not.toBeNull();
+ });
+ });
+
+ it('should set loaded to true when related records have been fetched and there are no results', async () => {
+ const ComponentToTest = ({ loaded }: { loaded?: boolean }) => {
+ return loaded: {loaded.toString()}
;
+ };
+
+ const { queryByText } = renderWithRedux(
+
+ {props => }
+ ,
+ {
+ admin: {
+ resources: {
+ bar: {
+ data: {
+ 1: { id: 1, title: 'hello' },
+ 2: { id: 2, title: 'world' },
+ },
+ },
+ },
+ references: {
+ oneToMany: {
+ 'foo_bar@fooId_barId': {
+ ids: [],
+ },
+ },
+ },
+ },
+ }
+ );
+
+ expect(queryByText('loaded: false')).not.toBeNull();
+ await waitFor(() => {
+ expect(queryByText('loaded: true')).not.toBeNull();
+ });
+ });
+
+ it('should set loaded to true when related records have been fetched and there are results', async () => {
+ const ComponentToTest = ({ loaded }: { loaded?: boolean }) => {
+ return loaded: {loaded.toString()}
;
+ };
+
+ const { queryByText } = renderWithRedux(
+
+ {props => }
+ ,
+ {
+ admin: {
+ resources: {
+ bar: {
+ data: {
+ 1: { id: 1, title: 'hello' },
+ 2: { id: 2, title: 'world' },
+ },
+ },
+ },
+ references: {
+ oneToMany: {
+ 'foo_bar@fooId_barId': {
+ ids: [1, 2],
+ },
+ },
+ },
+ },
+ }
+ );
+
+ expect(queryByText('loaded: false')).not.toBeNull();
+ await waitFor(() => {
+ expect(queryByText('loaded: true')).not.toBeNull();
+ });
+ });
+
+ it('should call dataProvider.getManyReferences on mount', async () => {
const children = jest.fn().mockReturnValue('children');
const { dispatch } = renderWithRedux(
', () => {
reference="bar"
target="foo_id"
basePath=""
+ record={{
+ id: 'fooId',
+ source: 'barId',
+ }}
>
{children}
,
diff --git a/packages/ra-core/src/dataProvider/useGetManyReference.ts b/packages/ra-core/src/dataProvider/useGetManyReference.ts
index 2eb8c6bfa03..092bef6a493 100644
--- a/packages/ra-core/src/dataProvider/useGetManyReference.ts
+++ b/packages/ra-core/src/dataProvider/useGetManyReference.ts
@@ -7,6 +7,8 @@ import {
SortPayload,
Identifier,
ReduxState,
+ Record,
+ RecordMap,
} from '../types';
import useQueryWithStore from './useQueryWithStore';
import {
@@ -93,19 +95,20 @@ const useGetManyReference = (
{ ...options, relatedTo, action: CRUD_GET_MANY_REFERENCE },
// ids and data selector
(state: ReduxState) => ({
- ids: getIds(state, relatedTo) || defaultIds,
+ ids: getIds(state, relatedTo),
allRecords: get(
state.admin.resources,
[resource, 'data'],
defaultData
),
}),
- (state: ReduxState) => getTotal(state, relatedTo)
+ (state: ReduxState) => getTotal(state, relatedTo),
+ isDataLoaded
);
const data = useMemo(
() =>
- ids === null
+ ids == null
? defaultData
: ids
.map(id => allRecords[id])
@@ -117,7 +120,14 @@ const useGetManyReference = (
[ids, allRecords]
);
- return { data, ids, total, error, loading, loaded };
+ return { data, ids: ids || defaultIds, total, error, loading, loaded };
};
+interface DataSelectorResult {
+ ids: Identifier[];
+ allRecords: RecordMap;
+}
+
+const isDataLoaded = (data: DataSelectorResult) => data.ids != null;
+
export default useGetManyReference;