Skip to main content

8.2 - fetchIfStale, expireAll, FormData with Collections

· 2 min read
Nathaniel Tucker

In 8.1 and 8.2 we added two new controller methods, along with some improvements to edge cases for Collections

Controller.expireAll

Similar to use case of invalidateAll(), but does not result in loading condition.

controller.expireAll() sets all responses' expiry status matching testKey to Stale.

This is sometimes useful to trigger refresh of only data presently shown when there are many parameterizations in cache.

import { type Controller, useController } from '@data-client/react';

const createTradeHandler = (ctrl: Controller) => async trade => {
await ctrl.fetch(TradeResource.getList.push({ user: user.id }, trade));
ctrl.expireAll(AccountResource.get);
ctrl.expireAll(AccountResource.getList);
};

function CreateTrade({ id }: { id: string }) {
const handleTrade = createTradeHandler(useController());

return (
<Form onSubmit={handleTrade}>
<FormField name="ticker" />
<FormField name="amount" type="number" />
<FormField name="price" type="number" />
</Form>
);
}

Controller.expireAll() PR

Controller.fetchIfStale

controller.fetchIfStale() fetches only if endpoint is considered 'stale'.

This can be useful when prefetching data, as it avoids overfetching fresh data.

An example with a fetch-as-you-render router:

{
name: 'IssueList',
component: lazyPage('IssuesPage'),
title: 'issue list',
resolveData: async (
controller: Controller,
{ owner, repo }: { owner: string; repo: string },
searchParams: URLSearchParams,
) => {
const q = searchParams?.get('q') || 'is:issue is:open';
await controller.fetchIfStale(IssueResource.search, {
owner,
repo,
q,
});
},
},

Stale

Date.now() <= expiresAt && expiryStatus !== ExpiryStatus.Invalid

Controller.fetchIfStale() PR

Collections and FormData

Collections can filter based on FormData arguments

ctrl.fetch(
getPosts.push,
{ group: 'react' },
new FormData(e.currentTarget),
);

Say our FormData contained an author field. Now that newly created item will be properly added to the collection list for that author.

useSuspense(getPosts, {
group: 'react',
author: 'bob',
});

In this case if FormData.get('author') === 'bob', it will show up in that useSuspense() call.

See more in the Collection nonFilterArgumentKeys example

Collections can filter based on FormData arguments PR