Skip to content

Commit

Permalink
Allow loading from DataLoader to be cancelled on unmount (#6283)
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya authored May 22, 2024
1 parent 0997cd8 commit bc5b173
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
16 changes: 12 additions & 4 deletions lms/static/scripts/frontend_apps/components/DataLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ export type DataLoaderProps<Data> = {
*/
children: ComponentChildren;

/** Function that fetches data if {@link loaded} is false. */
load: () => Promise<Data>;
/**
* Function that fetches data if {@link loaded} is false.
* It provides an abort signal that gets aborted when the DataLoader is
* unmounted or the `load` or `onLoad` props change.
*/
load: (signal: AbortSignal) => Promise<Data>;

/**
* Callback to invoke with the results of {@link load}.
Expand Down Expand Up @@ -46,13 +50,17 @@ export default function DataLoader<Data>({

useEffect(() => {
if (loaded) {
return;
return () => {};
}
load()

const controller = new AbortController();
load(controller.signal)
.then(onLoad)
.catch(err => {
setError(err);
});

return () => controller.abort();
}, [loaded, load, onLoad]);

if (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,19 @@ describe('DataLoader', () => {
assert.isFalse(wrapper.exists('[data-testid="content"]'));
assert.isFalse(wrapper.exists('SpinnerOverlay'));
});

it('aborts loading when DataLoader is unmounted', () => {
const onAbort = sinon.stub();
const wrapper = mount(
<TestContainer
load={async signal => {
signal.onabort = onAbort;
return 'Hello world';
}}
/>,
);

wrapper.unmount();
assert.called(onAbort);
});
});

0 comments on commit bc5b173

Please sign in to comment.