Skip to main content

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.

info

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.

todos.repository
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());