Trigger API
You will learn
In the previous chapters, we learned how to fetch data from the server and how to display it. Now let us talk about how to keep the data fresh.
.$stale property of the Query
Every Query has a .$stale property. It is a Store that contains a boolean value. It is true when the data in the Query is stale, and false when it is fresh.
By default, it is true because the Query is not fetched yet.
Data becomes stale when the Query in many cases:
- if it is updated after Mutation execution
- if it is dependent on another Query and the parent Query data is updated
- if its value is extracted from cache and the cache is not marked as fresh
In all these cases, the .$stale property of the Query becomes true and the Query immediately starts the process of refreshing the data.
Refresh the data manually
Sometimes you want to start a [Query] only if the data is stale and skip it if the data is fresh. For example, you got the data from the server and do not want to fetch it again until on client. For this case, you can use the .refresh Event of the Query.
import { sample } from 'effector';
import { createJsonQuery } from '@farfetched/core';
const someQuery = createJsonQuery({
/* ... */
});
sample({ clock: appStarted, target: someQuery.refresh });In this example, the someQuery will be started only every time when the appStarted event is triggered and the data in the someQuery is stale. You can safely call the appStarted on the server, transfer the data to the client, and call the appStarted on the client. The someQuery will be started only on the server and will be skipped on the client.
Refresh the data automatically
In the most cases, you want to refresh the data automatically during the lifetime of the app. For this case, you can use the keepFresh-operator.
The following example shows how to refresh the someQuery every time when $language store is changed, but only after the appStarted event is triggered.
import { keepFresh, createJsonQuery } from '@farfetched/core';
const $language = createStore('en');
const someQuery = createJsonQuery({
request: {
url: { source: $language, fn: (_, language) => `/api/${language}` },
},
});
keepFresh(someQuery, {
automatically: true,
});
sample({ clock: appStarted, target: someQuery.refresh });If you do want to refresh the data immediately after some external trigger, you can use triggers field of the keepFresh-operator's config to specify the triggers.
import { keepFresh, createJsonQuery } from '@farfetched/core';
const $language = createStore('en');
const someQuery = createJsonQuery(/* ... */);
keepFresh(someQuery, { triggers: [userLoggedIn] });
sample({ clock: appStarted, target: someQuery.refresh });External triggers
Trigger API is based on @@trigger-protocol, so any library that implements this protocol can be used as a trigger.
Web APIs
It could be really useful to refresh the data on some application wide triggers like tab visibility or network reconnection. This kind of triggers is out of scope of Farfetched, so they are distributed as separated package — @withease/web-api.
pnpm install @withease/web-apiyarn add @withease/web-apinpm install @withease/web-apiIt is compatible with Farfetched and can be used without any additional configuration.
import { trackPageVisibility, trackNetworkStatus } from '@withease/web-api';
import { keepFresh } from '@farfetched/core';
keepFresh(someQuery, {
triggers: [trackPageVisibility, trackNetworkStatus],
});Check documentation of @withease/web-api for the complete list of available triggers.
Interval
If you want to refresh the data every N seconds, you can use the interval method from patronum which is library with numerous utilities for Effector.
pnpm install patronumyarn add patronumnpm install patronumIt is compatible with Farfetched and can be used without any additional configuration.
import { keepFresh } from '@farfetched/core';
import { interval } from 'patronum';
keepFresh(someQuery, {
// 👇 someQuery will be refreshed every 5 seconds
triggers: [interval({ timeout: 5000 })],
});Check documentation of patronum/interval for the complete documentation.
Mix automatic and manual refresh
You can mix automatic and manual refresh:
keepFresh(someQuery, {
automatically: true,
triggers: [userLoggedIn],
});API reference
You can find the full API reference for the keepFresh operator in the API reference.