Skip to content

Commit

Permalink
Update paginationMachine.js
Browse files Browse the repository at this point in the history
  • Loading branch information
adamrybinski authored Nov 2, 2021
1 parent e32aeb1 commit 806614d
Showing 1 changed file with 117 additions and 65 deletions.
182 changes: 117 additions & 65 deletions paginationMachine.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,123 @@
import { assign, createMachine } from './deps.js';
import { assign, createMachine } from 'xstate';
import { choose } from 'xstate/lib/actions';

const infiniteScrollMachine = createMachine({
id: 'infiniteScroll',
initial: 'fetchingRowOfData',
context: {
totalEntries: Infinity,
data: []
},
states: {
fetchingRowOfData: {
on: {
RECEIVED_DATA: {
target: 'checkingIfThereIsMoreData',
actions: ['assignDataToContext']
}
},
invoke: {
src: 'fetchRowOfData',
onError: {
target: 'idle',
actions: 'assignErrorMessageToContext'
}
}
export interface PaginationMachineContext {
totalPages?: number;
/**
* This page is 1-indexed, not 0-indexed
*/
currentPage: number;
}

export type PaginationMachineEvent =
| {
type: 'UPDATE_TOTAL_PAGES';
totalPages: number;
}
| {
type: 'NEXT_PAGE';
}
| {
type: 'PREV_PAGE';
}
| {
type: 'GO_TO_TARGET_PAGE';
targetPage: number;
};

const paginationMachine = createMachine<
PaginationMachineContext,
PaginationMachineEvent
>(
{
id: 'pagination',
initial: 'awaitingTotalPages',
context: {
currentPage: 1,
},
idle: {
exit: ['clearErrorMessage'],
on: {
SCROLL_TO_BOTTOM: 'fetchingRowOfData'
}
on: {
UPDATE_TOTAL_PAGES: {
cond: 'newTotalPagesIsValidValue',
actions: choose([
{
cond: 'currentPageIsAboveNewTotalPages',
actions: ['assignTotalPagesToContext', 'goToFirstPage'],
},
{
actions: ['assignTotalPagesToContext'],
},
]),
target: 'idle',
},
},
checkingIfThereIsMoreData: {
always: [{
cond: 'thereIsMoreData',
target: 'idle'
}, {
target: 'noMoreDataToFetch'
}]
states: {
awaitingTotalPages: {},
idle: {
on: {
NEXT_PAGE: {
cond: 'canGoToNextPage',
actions: 'goToNextPage',
},
PREV_PAGE: {
cond: 'canGoToPrevPage',
actions: 'goToPrevPage',
},
GO_TO_TARGET_PAGE: {
actions: 'goToTargetPage',
cond: 'targetPageIsWithinBounds',
},
},
},
},
noMoreDataToFetch: {
type: 'final'
}
}
}, {
guards: {
thereIsMoreData: context => {
return context.totalEntries > context.data.length;
}
},
services: {
fetchRowOfData: () => send => {}
{
guards: {
newTotalPagesIsValidValue: (context, event) => {
if (event.type !== 'UPDATE_TOTAL_PAGES') return false;

return event.totalPages > 0;
},
currentPageIsAboveNewTotalPages: (context, event) => {
if (event.type !== 'UPDATE_TOTAL_PAGES') return false;

return context.currentPage > event.totalPages;
},
canGoToNextPage: (context) => {
return context.currentPage < context.totalPages;
},
canGoToPrevPage: (context) => {
return context.currentPage > 1;
},
targetPageIsWithinBounds: (context, event) => {
if (event.type !== 'GO_TO_TARGET_PAGE') return false;
return event.targetPage >= 1 && event.targetPage <= context.totalPages;
},
},
actions: {
goToFirstPage: assign({
currentPage: 1,
}),
goToPrevPage: assign({
currentPage: (context) => context.currentPage - 1,
}),
goToNextPage: assign({
currentPage: (context) => context.currentPage + 1,
}),
goToTargetPage: assign((context, event) => {
if (event.type !== 'GO_TO_TARGET_PAGE') return {};

return {
currentPage: event.targetPage,
};
}),
assignTotalPagesToContext: assign((context, event) => {
if (event.type !== 'UPDATE_TOTAL_PAGES') return {};
return {
totalPages: event.totalPages,
};
}),
},
},
actions: {
assignDataToContext: assign((context, event) => {
if (event.type !== 'RECEIVED_DATA') return {};
return {
data: [...context.data, ...event.data],
totalEntries: event.totalEntries
};
}),
clearErrorMessage: assign(context => ({
errorMessage: undefined
})),
assignErrorMessageToContext: assign((context, event) => {
return {
errorMessage: event.data?.message || 'An unknown error occurred'
};
})
}
});
export default infiniteScrollMachine;
);

export default paginationMachine;

0 comments on commit 806614d

Please sign in to comment.