Skip to content

Commit

Permalink
Merge pull request #6080 from marmelab/fix-ReferenceArrayField-loaded…
Browse files Browse the repository at this point in the history
…-data

Fix ReferenceArrayField passes empty data to child when loaded
  • Loading branch information
djhi authored Mar 26, 2021
2 parents 4c62d18 + 5ead8c0 commit ee9afd6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ const useReferenceArrayFieldController = (
),
});

const [loadingState, setLoadingState] = useSafeSetState<boolean>(loading);
const [loadedState, setLoadedState] = useSafeSetState<boolean>(loaded);

const [finalData, setFinalData] = useSafeSetState<RecordMap>(
indexById(data)
);
Expand Down Expand Up @@ -211,6 +214,18 @@ const useReferenceArrayFieldController = (
sort.order,
]);

useEffect(() => {
if (loaded !== loadedState) {
setLoadedState(loaded);
}
}, [loaded, loadedState, setLoadedState]);

useEffect(() => {
if (loading !== loadingState) {
setLoadingState(loading);
}
}, [loading, loadingState, setLoadingState]);

return {
basePath: basePath.replace(resource, reference),
currentSort: sort,
Expand All @@ -222,8 +237,8 @@ const useReferenceArrayFieldController = (
hasCreate: false,
hideFilter,
ids: finalIds,
loaded,
loading,
loaded: loadedState,
loading: loadingState,
onSelect,
onToggleItem,
onUnselectItems,
Expand Down
47 changes: 44 additions & 3 deletions packages/ra-ui-materialui/src/field/ReferenceArrayField.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import * as React from 'react';
import expect from 'expect';
import { render } from '@testing-library/react';
import { render, act } from '@testing-library/react';
import { renderWithRedux } from 'ra-test';
import { MemoryRouter } from 'react-router-dom';
import { ListContextProvider } from 'ra-core';
import { ListContextProvider, DataProviderContext } from 'ra-core';

import { ReferenceArrayFieldView } from './ReferenceArrayField';
import ReferenceArrayField, {
ReferenceArrayFieldView,
} from './ReferenceArrayField';
import TextField from './TextField';
import SingleFieldList from '../list/SingleFieldList';

Expand Down Expand Up @@ -203,4 +206,42 @@ describe('<ReferenceArrayField />', () => {
);
expect(container.getElementsByClassName('myClass')).toHaveLength(1);
});

it('should have defined data when loaded', async () => {
let resolve;
const promise = new Promise<any>(res => {
resolve = res;
});
const WeakField = ({ record }: any) => <div>{record.title}</div>;
const dataProvider = {
getMany: () =>
promise.then(() => ({
data: [
{ id: 1, title: 'bar1' },
{ id: 2, title: 'bar2' },
],
})),
};
const { queryByText } = renderWithRedux(
<DataProviderContext.Provider value={dataProvider}>
<ReferenceArrayField
record={{ id: 123, barIds: [1, 2] }}
className="myClass"
resource="foos"
reference="bars"
source="barIds"
basePath="/foos"
>
<SingleFieldList linkType={false}>
<WeakField />
</SingleFieldList>
</ReferenceArrayField>
</DataProviderContext.Provider>,
{ admin: { resources: { bars: { data: {} } } } }
);
expect(queryByText('bar1')).toBeNull();
act(() => resolve());
await new Promise(resolve => setTimeout(resolve)); // wait for loaded to be true
expect(queryByText('bar1')).not.toBeNull();
});
});

0 comments on commit ee9afd6

Please sign in to comment.