Requests Result
Elf provides a convenient way to track the status
of async requests and combine it with your store selectors. 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
Now, simply add to your source request the trackRequestResult
operator, and give it a unique key
:
todos.service.ts
import { trackRequestResult } from '@ngneat/elf-requests';
import { setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos),
trackRequestResult(['todos'])
);
}
Now, we can use the joinRequestResult
operator with our store selectors:
todos.repository
import { createStore } from '@ngneat/elf';
import { withEntities } from '@ngneat/elf-entities';
import { joinRequestResult } from '@ngneat/elf-requests';
interface Todo {
id: number;
label: string;
}
const todosStore = createStore({ name: 'todos' }, withEntities<Todo>());
export const entities$ = store.pipe(
selectAllEntities(),
joinRequestResult(['todos'])
);
The entities$
selector will now track the todos
request and will provide the following information:
entities$.subscribe(
({ isLoading, isError, isSuccess, data, error, status }) => {
console.log(
isLoading,
isError,
isSuccess,
status,
successfulRequestsCount,
data, // typed as Todo[]
error
);
}
);
We can also initialize the selector as idle
by using joinRequestResult(['todos'], { initialStatus: 'idle' })
Here is an example of a dynamic
selector:
export const selectTodo = (id: Todo['id]) => store.pipe(
selectEntity(id),
joinRequestResult(['todos', id])
);
Additional Options
staleTime
- When we should refetch
todos.service.ts
import { trackRequestResult } from '@ngneat/elf-requests';
import { setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos),
trackRequestResult(['todos'], { staleTime: 10_000 })
);
}
skipCache
- Ignore everything and perform the request
todos.service.ts
import { trackRequestResult } from '@ngneat/elf-requests';
import { setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos),
trackRequestResult(['todos'], { skipCache: true })
);
}
preventConcurrentRequest
- Don't perform the request if there is a pending request, defaults totrue
todos.service.ts
import { trackRequestResult } from '@ngneat/elf-requests';
import { setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos),
trackRequestResult(['todos'], { preventConcurrentRequest: false })
);
}
cacheResponseData
- Cache the response data and emit it as responseData for skipped requests, defaults tofalse
todos.service.ts
import { trackRequestResult } from '@ngneat/elf-requests';
import { setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos),
trackRequestResult(['todos'], { cacheResponseData: true })
);
}
fetchTodos().subscribe((todos) => {
// This will be called with the cached result, or once the request is completed
});
additionalKeys
- Cache the request result for additional keys, e.g. based on properties from the response data
todos.service.ts
import { trackRequestResult } from '@ngneat/elf-requests';
import { setTodos } from './todos.repository';
export function fetchTodos() {
return http.get(todosUrl).pipe(
tap(setTodos),
trackRequestResult(['todos'], { additionalKeys: todos => todos.map(todo => (['todos', todo.id])) })
);
}
Operators
import { filterSuccess, filterError } from '@ngneat/elf-requests';
entities$.pipe(filterSuccess()).subscribe((result) => {
// This will be called only upon success
});
entities$.pipe(filterError()).subscribe((result) => {
// This will be called only upon error
});
entities$
.pipe(
mapResultData((data) => {
// This will be called only when data is defined (not `null` or `undefined`)
return data.filter((todo) => todo.id === 1);
})
)
.subscribe((result) => {});
API
getRequestResult
-getRequestResult(key): Observable<RequestResult>
deleteRequestResult
-deleteRequestResult(key): void
resetStaleTime
-resetStaleTime(key): void
clearRequestsResult
-clearRequestsResult(): void