Unify Logo Footer.svg
Unify Applications
Logo
Infinite Loading

Infinite Loading

Logo

6 mins READ

Infinite Loading

Infinite loading turns a data source's response from one fixed window into an append-only list: the first run fetches a page, and consuming blocks can keep asking for the next page — on scroll or a "Load More" control — with each new page added below the ones already shown. The user sees one continuously growing list; behind it the data source issues one request per page.

Which Data Sources Load Infinitely

Infinite loading is not a toggle you flip — it activates automatically for platform operations that return lists the platform knows how to page.

Operation typeInfinite loadingNote
Platform query — multiple records (numberOfRecordsToFetch: MULTIPLE)YesSwitching to SINGLE makes it a plain one-fetch source.
Audit queriesYesAlways infinite.
Standard entity fetchesYesAlways infinite.
Analytics query reportsYesAlways infinite.
Callable automations (list-returning)YesAlways infinite.
API endpoint or single-record platform queryNoReturns one response. Use offset/limit in the query to page by replacement.

How Paging is Wired

An infinite data source's pagination is described by a handful of internal paths that tell the platform where paging information lives in the request and response.

Paging signalDefault pathDescription
Items arrayobjectsThe path in the response holding the actual items to append.
Page size20Records per page. Configured via the request's limit input.
Offset0Starting position. Advances by page size after each fetch.
Paging strategyOffset-basedDefault is offset (count-based). Some operations support cursor-based paging — the platform follows the response's cursor instead of counting items.
Has-more signalhasMoreA boolean flag in the response. When present, this is the definitive signal for whether more pages exist.
Total countFallback when no has-more flag: the platform compares total count against records fetched so far.

Has-Next-Page Decision Logic

The "is there more?" decision follows a strict precedence:

  1. Has-more flag — if a boolean hasMore path is configured and the response provides it, this wins.

  2. Total count — fallback: more pages exist while the total count exceeds what's been fetched so far.

  3. Neither available — loading stops after the current page with no error. The list simply never grows.

What Consuming Blocks See

Blocks bound to an infinite data source read one combined response, not a stack of pages.

Exposed state keyDescription
data.objectsEvery fetched page's items combined into one flat array, in order. New items append as pages load.
isLoadingTrue during the very first page fetch.
isFetchingTrue during any fetch — first page or subsequent pages.
isFetchingNextPageTrue specifically while a next-page fetch is in flight. Use this to show a "loading more" indicator without hiding the already-loaded items.
hasNextPageTrue while more pages exist. Use to conditionally show/hide a "Load More" button or end-of-list message.
errorPresent when the last page fetch failed.

Note: Table, Timeline, and similar list-style blocks that consume data sources request the next page themselves when the user reaches the end. You do not need to wire a "fetch next page" action manually for scroll-based pagination in these blocks.

Binding Example

Example — Binding an infinite data source to a repeatable list

// Data source: orders_list (infinite, returns multiple records) // Repeatable's content property: {{ orders_list.data.objects }} // Show a loading-more indicator: {{ orders_list.isFetchingNextPage }} // Show "Load More" button only when more exist: visibility: {{ orders_list.hasNextPage }} // Show end-of-list message when done: visibility: {{ !orders_list.hasNextPage && !orders_list.isLoading }}

When Inputs Change

Changing a bound input (filter, sort, search) starts the list over: the new inputs define a new result set, so paging restarts from the first page rather than appending mismatched results. The previously loaded list stays visible while the fresh first page loads — the block doesn't blank out during the switch.

Tip: You don't need to manually reset pagination state when a filter changes. The infinite data source detects the input change and automatically resets to page 1 on the next render cycle.

Transforms and Infinite Loading

A response transform on an infinite data source runs per page. The transformed pages' item lists are combined — but the has-more flag and total count are read from the transformed response, not the raw one. If your transform returns only the items array and discards the paging signals, "Load More" silently stops after the first page.

Warning: When using a transform on an infinite data source, preserve the hasMore flag (and/or total count) in whatever shape your transform returns. Dropping them causes the first page to look like the last.

Offset Paging vs Infinite Loading

BehaviorOffset pagingInfinite loading
New pages replace or append?Replace — shows a different windowAppend — grows the list downward
How configuredLimit + offset inputs in the Query BuilderAutomatic for supported operation types
Scroll-to-load behaviorNot automatic — requires action wiringBuilt in to list-style blocks
Binding path{{ ds.data.objects }} (one page at a time){{ ds.data.objects }} (all loaded pages combined)

Gotchas

GotchaDetails
No paging signal = one page, silentlyIf the response exposes neither a has-more flag nor a usable numeric total, loading ends after the first page with no error — the list just never grows.
A transform that drops paging signalsReturning only the items array from a transform strips the has-more flag. "Load More" stops after page 1 with no error or warning.
Non-list fields show the latest page onlyAny per-page metadata (such as a page-scoped count) reflects the last fetch, not the accumulated total. Binding a "total shown" label to such a field will look wrong after page two.
Not a toggleYou cannot independently turn infinite loading on or off for an arbitrary data source. It is determined by the operation type. To get a plain one-fetch source, change the operation to return a single record.

Frequently Asked Questions

How do I know if my data source supports infinite loading?

Infinite loading activates automatically for platform operations that return lists the platform can page: entity record fetches (configured for multiple records), audit queries, analytics reports, and callable automations. You cannot turn it on or off independently — it is determined by the operation type. If a data source returns a single response with no paging signals, it is not an infinite source.

My "Load More" button stops working after the first page. What's wrong?

The most likely cause is a response transform that returns only the items array, dropping the hasMore flag or total count that tells the platform there are more pages. Check your transform code and ensure it returns the full page object, including the paging signals. Without those signals, the platform assumes the first page is the last.

Does changing a filter reset the pagination back to page 1?

Yes — when any bound input (filter, sort, search) changes, the infinite data source automatically restarts from page 1. The new inputs define a new result set, so pages from the old set would be mismatched. The previously loaded items stay visible while the fresh first page loads, so the block doesn't flash empty during the transition.

How do I show an end-of-list message when all records have loaded?

Bind a block's visibility to {{ !my_datasource.hasNextPage && !my_datasource.isLoading }}. When hasNextPage is false and the source is not loading, all pages have been fetched. You can pair this with isFetchingNextPage to show a "loading more" indicator while intermediate pages are in flight.