Cache
Using this feature, you can manage the cache status of API calls in your store. First, you need to install the package
by using the CLI command elf-cli install
and selecting the requests package, or via npm:
npm i @ngneat/elf-requests
To use this feature, provide the withRequestsCache
props factory function in the createStore
call:
import { createStore } from '@ngneat/elf';
import { withEntities } from '@ngneat/elf-entities';
import { withRequestsCache } from '@ngneat/elf-requests';
interface Todo {
id: number;
label: string;
}
const todosStore = createStore(
{ name: 'todos' },
withEntities<Todo>(),
// You can pass the keys type
withRequestsCache<'todo'|`todo-${string}`>()
);
Now we can use the createRequestsCacheOperator
function that takes a store and returns a custom operator.
import {
withRequestsCache,
createRequestsCacheOperator,
} from '@ngneat/elf-requests';
const todosStore = createStore(
{ name: 'todos' },
withEntities<Todo>(),
withRequestsCache<'todo'|`todo-${string}`>()
);
export const skipWhileTodosCached = createRequestsCacheOperator(todosStore);
We can use the resulting operator and pass a unique key to identify the request. This enables skipping the API call if the passed key is located in the store cache.
import { setTodos, skipWhileTodosCached } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos(todos)),
skipWhileTodosCached('todos')
);
}
Use it in tandem with updateRequestsCache
:
import { updateRequestCache } from '@ngneat/elf-requests';
import { setEntities } from '@ngneat/elf-entities';
export function setTodos(todos: Todo[]) {
store.update(
updateRequestCache('todos'),
setEntities(todos)
);
}
Passing a value as the third parameter ensures the store
will only skip the API call if the value matches the
one passed. Values can be 'none', 'partial' or 'full':
import { updateRequestCache } from '@ngneat/elf-requests';
export function setTodos(todos: Todo[]) {
store.update(
updateRequestCache('todos', { value: 'partial' }),
setEntities(todos)
);
}
import { setTodos, skipWhileTodosCached } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap((todos) => setTodos(todos)),
skipWhileTodosCached('todos', { value: 'partial' })
);
}
In addition to value, you can pass in the same object a returnSource
which will be returned by the operator if the
request is cached. The default return value is EMPTY
observable.
import { skipWhileTodosCached, setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap((todos) => setTodos(todos)),
skipWhileTodosCached('todos', { returnSource: of([]) })
);
}
You can monitor and change the request cache status for your APIs using the following queries and mutations:
Queries
selectRequestCache
Select the cache status of the provided request key:
import { selectRequestCache } from '@ngneat/elf-requests';
todosCacheStatus$ = store.pipe(selectRequestCache('todos'));
getRequestCache
Get the cache status of the provided request key:
import { getRequestCache } from '@ngneat/elf-requests';
todosCacheStatus = store.query(getRequestCache('todos'));
selectIsRequestCached
Select whether the cache status of the provided request key isn't none
:
import { selectIsRequestCached } from '@ngneat/elf-requests';
const isCached$ = store.pipe(selectIsRequestCached('todos'));
const isPartialCached$ = store.pipe(
selectIsRequestCached('todos', { value: 'partial' })
);
Get whether the cache status of the provided request key isn't none
:
import { isRequestCached } from '@ngneat/elf-requests';
const isCached = store.query(isRequestCached('todos'));
const isPartialCached = store.query(
isRequestCached('todos', { value: 'partial' })
);
Mutations
updateRequestCache
import { updateRequestCache } from '@ngneat/elf-requests';
store.update(updateRequestCache('todos'));
store.update(updateRequestCache('todos', { value: 'partial' }));
store.update(updateRequestCache('todos', { value: 'none' }));
store.update(updateRequestCache('todos', { ttl: 1000 }));
If you pass ttl
(time to live) when updating a cache record, that represents the time (in milliseconds) that key
will
have the value that was set (afterward, it reverts to 'none').
updateRequestsCache
import { updateRequestsCache } from '@ngneat/elf-requests';
store.update(
updateRequestsCache({
keyOne: {
value: 'partial',
},
})
);
store.update(updateRequestsCache(['keyOne', 'keyTwo'], { value: 'partial' }));
store.update(
updateRequestsCache(['keyOne', 'keyTwo'], { value: 'partial', ttl: 1000 })
);
If you pass ttl
(time to live) when updating a cache record, that represents the time (in milliseconds) that key will
have the value that was set (afterward, it reverts to 'none'). This parameter can be used to set individual ttl
values for each key when updating multiple keys at once. If a ttl
is not passed for a key, the value for that key does not expire.
clearRequestsCache
import { clearRequestsCache } from '@ngneat/elf-requests';
store.update(clearRequestsCache());
deleteRequestsCache
import { deleteRequestsCache } from '@ngneat/elf-requests';
store.update(deleteRequestsCache('keyOne'));
store.update(deleteRequestsCache(['keyOne', 'keyTwo']));