Photo by Joan Gamell on Unsplash

Mastering Pagination with fetchPaginatedData: A TypeScript Guide

Learn how to build a versatile pagination function to enhance your API wrapper

Kris
3 min readMar 28, 2023

--

Why should you learn about that?

When working with APIs, handling paginated data is a common challenge developers face. To manage large datasets and limit the strain on servers, APIs often return paginated data. In this article, we will explore the fetchPaginatedData function, a powerful and versatile pagination function built using TypeScript, and discuss how it can simplify your API wrapper.

What is the goal of the function?

Providing a seamless experience for users while gracefully handling paginated data is essential. The fetchPaginatedData function aims to address this challenge and deliver an effective solution.

Building the fetchPaginatedData Function

fetchPaginatedData is a generic TypeScript function designed to handle pagination effortlessly. Before diving into the function itself, let's define the PaginatedResult and NextFunction types, which will be used to provide better type safety and readability:

type PaginatedResult<T> = {
data: T[];
next: NextFunction<T> | null;
};

type NextFunction<T> = () => Promise<PaginatedResult<T> | null>;

PaginatedResult<T> represents the result of fetching a single page of data, including the data itself and a next function to fetch the next page. NextFunction<T> represents the type of the next function, which returns a Promise that resolves to a PaginatedResult<T> or null if there are no more pages.

Now let’s dive into the structure of the fetchPaginatedData function:

async function fetchPaginatedData<T>(
endpoint: string,
params: { currentPage: number; pageSize: number; [key: string]: any }
): Promise<PaginatedResult<T>> {
// ...implementation details
}

The function’s structure includes:

  • A generic function with a type parameter T, allows it to handle different data types.
  • Input parameters: endpoint (API endpoint) and params (an object containing pagination-related parameters and any additional parameters required by the API).
  • A return type: a Promise that resolves to a PaginatedResult<T> object containing an array of results (T[]) and a next function.

By using the PaginatedResult and NextFunction types, we can ensure that our fetchPaginatedData function is more type-safe, readable, and easier to maintain. This approach makes it clear what each part of the function is responsible for and helps us avoid potential type-related issues.

Implementing the fetchPaginatedData Function

Let’s now examine the implementation details of the fetchPaginatedData function:

async function fetchPaginatedData<T>(
endpoint: string,
params: { currentPage: number; pageSize: number; [key: string]: any }
): Promise<PaginatedResult<T>> {
const { currentPage, pageSize, ...otherParams } = params;
const queryString = new URLSearchParams({ ...otherParams, currentPage, pageSize }).toString();
const url = `${endpoint}?${queryString}`;

try {
const response = await fetch(url);
const data: T = await response.json();

const totalResults = 'totalResults' in data ? (data as any)['totalResults'] : undefined;
const hasMoreResults = currentPage * pageSize < totalResults;

const next: NextFunction<T> | null = hasMoreResults
? async () => {
return fetchPaginatedData<T>(endpoint, { ...params, currentPage: currentPage + 1 });
}
: null;

return { data, next };
} catch (error) {
throw new Error(`Error fetching paginated data: ${error}`);
}
}

This implementation includes:

  • Extracting pagination parameters and constructing the API request URL.
  • Fetching data and parsing it as JSON.
  • Checking if there are more results available.
  • Defining the next function based on the availability of more results.

Using the fetchPaginatedData Function

Here’s an example of how to use the fetchPaginatedData function to handle paginated data from a hypothetical API:

async function getPosts(page: number) {
const results = await fetchPaginatedData<Post>("/api/posts", { currentPage: page, pageSize: 10 });

console.log("Current page results:", results.data);

if (results.next) {
console.log("There are more results available");
const nextResults = results.next();
} else {
console.log("No more results available");
}
}

getPosts(1);

Conclusion

With the fetchPaginatedData function, you can easily handle paginated API data in your TypeScript projects. It's a powerful, reusable tool that can significantly enhance your API wrapper, making it more efficient and user-friendly. Happy coding!

--

--

Kris
0 Followers

Dedicated to sharing insights on programming, finance, and emerging technologies.