From caf1af8aed68110b1826bb69da0e6a5b4ac1a0a6 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Kaiser Date: Wed, 24 May 2023 10:21:09 +0200 Subject: [PATCH 1/2] Fix `useGetList` default `onSuccess` throws when the query is disabled --- .../src/dataProvider/useGetList.spec.tsx | 31 +++++++++++++++++++ .../ra-core/src/dataProvider/useGetList.ts | 3 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/ra-core/src/dataProvider/useGetList.spec.tsx b/packages/ra-core/src/dataProvider/useGetList.spec.tsx index 956930f1adf..29702e7edd4 100644 --- a/packages/ra-core/src/dataProvider/useGetList.spec.tsx +++ b/packages/ra-core/src/dataProvider/useGetList.spec.tsx @@ -5,6 +5,7 @@ import { QueryClient } from 'react-query'; import { CoreAdminContext } from '../core'; import { useGetList } from './useGetList'; +import { DataProvider } from '../types'; const UseGetList = ({ resource = 'posts', @@ -343,4 +344,34 @@ describe('useGetList', () => { queryClient.getQueryData(['posts', 'getOne', { id: '1' }]) ).toEqual({ id: 1, title: 'live' }); }); + + it('should not fail when the query is disabled and the cache gets updated by another query', async () => { + const callback: any = jest.fn(); + const onSuccess = jest.fn(); + const queryClient = new QueryClient(); + const dataProvider = ({ + getList: jest.fn(() => + Promise.resolve({ data: [{ id: 1, title: 'live' }], total: 1 }) + ), + delete: jest.fn(), + } as unknown) as DataProvider; + render( + + + + ); + await waitFor(() => { + expect(callback).toHaveBeenCalled(); + }); + queryClient.setQueriesData(['posts', 'getList'], res => res); + await waitFor(() => { + expect(onSuccess).toHaveBeenCalled(); + }); + }); }); diff --git a/packages/ra-core/src/dataProvider/useGetList.ts b/packages/ra-core/src/dataProvider/useGetList.ts index 6c2fc418708..27d5bb607b7 100644 --- a/packages/ra-core/src/dataProvider/useGetList.ts +++ b/packages/ra-core/src/dataProvider/useGetList.ts @@ -86,9 +86,8 @@ export const useGetList = ( { ...options, onSuccess: value => { - const { data } = value; // optimistically populate the getOne cache - data.forEach(record => { + value?.data?.forEach(record => { queryClient.setQueryData( [resource, 'getOne', { id: String(record.id), meta }], oldRecord => oldRecord ?? record From 3be844fa7741e90af4e162caa5b9f753eafdd82e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Kaiser Date: Wed, 24 May 2023 10:23:45 +0200 Subject: [PATCH 2/2] improve test comments --- packages/ra-core/src/dataProvider/useGetList.spec.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ra-core/src/dataProvider/useGetList.spec.tsx b/packages/ra-core/src/dataProvider/useGetList.spec.tsx index 29702e7edd4..3fb8838873b 100644 --- a/packages/ra-core/src/dataProvider/useGetList.spec.tsx +++ b/packages/ra-core/src/dataProvider/useGetList.spec.tsx @@ -353,7 +353,6 @@ describe('useGetList', () => { getList: jest.fn(() => Promise.resolve({ data: [{ id: 1, title: 'live' }], total: 1 }) ), - delete: jest.fn(), } as unknown) as DataProvider; render( { await waitFor(() => { expect(callback).toHaveBeenCalled(); }); + // Simulate the side-effect of e.g. a call to delete queryClient.setQueriesData(['posts', 'getList'], res => res); + // If we get this far without an error being thrown, the test passes await waitFor(() => { expect(onSuccess).toHaveBeenCalled(); });