Pagination
In many cases - for example, when working with very large data-sets - we don't want to work with the full collection in memory. Instead, server-side pagination is used, where the server sends just a single page of data at a time.
Usually, we also want to cache pages that already have been fetched, in order to spare the need for an additional request.
This feature requires @ngneat/elf-entities
Using this feature, you can manage pagination by using the store. First, you need to install the package by using
the CLI command elf-cli install
and selecting the pagination package, or via npm:
npm i @ngneat/elf-pagination
To use this feature, provide the withPagination
props factory function in the createStore
call:
import { createStore } from '@ngneat/elf';
import { withEntities } from '@ngneat/elf-entities';
import { withPagination } from '@ngneat/elf-pagination';
interface Todo {
id: number;
label: string;
}
const todosStore = createStore(
{ name: 'todos' },
withEntities<Todo>(),
withPagination()
);
Call updatePaginationData()
with a configuration object that determines the various pagination settings, and call setPage()
whenever you want to define the ids
that belong to a certain page number.
Note: pagination can start at index 0 or 1.
import { PaginationData } from '@ngneat/elf-pagination';
export function addTodos(response: PaginationData & { data: Todo[] }) {
const { data, ...paginationData } = response;
todosStore.update(
addEntities(todos),
updatePaginationData(paginationData),
setPage(
1,
data.map((c) => c.id)
)
);
}
In your server calls, you can use the skipWhilePageExists
operator, which enables you to skip server calls
if the page exists in the store:
import { skipWhilePageExists } from '@ngneat/elf-pagination';
export function getTodosPage(page: number) {
return http.get(todosUrl).pipe(
tap((todos) => addTodos(todos)),
skipWhilePageExists(page)
);
}
Additional queries and mutations available are:
Queries
selectCurrentPageEntities
Select the current page entities:
import { selectCurrentPageEntities } from '@ngneat/elf-pagination';
todos$ = store.pipe(selectCurrentPageEntities());
selectCurrentPage
Select the current page number (by default it's page 1):
import { selectCurrentPage } from '@ngneat/elf-pagination';
currentPage$ = store.pipe(selectCurrentPage());
selectHasPage
Select whether the page exists:
import { selectHasPage } from '@ngneat/elf-pagination';
hasPage$ = store.pipe(selectHasPage(1));
hasPage
Get whether the page exists:
import { hasPage } from '@ngneat/elf-pagination';
hasPage = store.query(hasPage(1));
selectPaginationData
Select the pagination data:
import { selectPaginationData } from '@ngneat/elf-pagination';
data$ = store.pipe(selectPaginationData());
getPaginationData
Get pagination data:
import { getPaginationData } from '@ngneat/elf-pagination';
data = store.query(getPaginationData());
Mutations
setCurrentPage
Set the current page:
import { setCurrentPage } from '@ngneat/elf-pagination';
store.update(setCurrentPage(2));
setPage
Set the ids belongs to a page:
import { setPage } from '@ngneat/elf-pagination';
store.update(setPage(2, [id, id, id]));
updatePaginationData
Set the current page:
import { updatePaginationData } from '@ngneat/elf-pagination';
store.update(
updatePaginationData({
currentPage: 1,
perPage: 10,
total: 96,
lastPage: 10,
})
);
deletePage
Delete a page:
import { deletePage } from '@ngneat/elf-pagination';
store.update(deletePage(2));
deleteAllPages
Delete all pages:
import { deleteAllPages } from '@ngneat/elf-pagination';
store.update(deleteAllPages());