Auto-Pagination & Smart Polling
Iterate paginated endpoints without manual while loops, and poll asynchronous backend tasks with exponential backoff.
1. Iterate Items (api.paginate())
The callable api.paginate() helper yields individual items across page boundaries automatically:
paginate.ts
typescript
type Product = { id: string; name: string };
// Async generator yields individual items one by one:
for await (const product of api.paginate<Product>('/products', {
pagination: {
type: 'page',
pageParam: 'page',
pageSizeParam: 'limit',
pageSize: 20,
},
})) {
console.log(product.name);
}2. Iterate Complete Page Responses (api.paginate.pages())
Use api.paginate.pages() when your code needs access to response headers and HTTP status codes:
typescript
// Yields full page response envelopes:
for await (const page of api.paginate.pages<Product[]>('/products', {
pagination: { type: 'page', pageSize: 20 },
})) {
console.log(page.status, page.data.length);
}3. Collect All Items (api.paginate.all())
Aggregate all items across all pages into a single flat array:
typescript
// Collects all items across pages into one array:
const products = await api.paginate.all<Product>('/products', {
pagination: {
type: 'page',
pageSize: 50,
maxPages: 5, // Safety limit
},
});
console.log('Total items fetched:', products.length);4. Smart Polling (api.poll())
Poll an endpoint until a predicate condition is met:
typescript
// Poll an asynchronous backend job until completed:
const response = await api.poll<{ status: string; result?: any }>('/jobs/99', {
interval: 1000,
backoff: 1.5, // 1s, 1.5s, 2.25s...
timeout: 30000,
until: (res) => res.data?.status === 'COMPLETED',
});
console.log('Job finished:', response.data.result);Overall Timeout & Immediate Cancellation
The
timeout option enforces a hard deadline across the entire polling lifecycle. If an individual request hangs or total polling duration exceeds the deadline, the in-flight request is cleanly aborted and a TimeoutError is thrown. Passing an signal allows instant cancellation at any moment—even during backoff delays—clearing timers immediately.Four Pagination Strategies Supported
The pagination engine supports
page (page numbers), offset (limit/offset), cursor (cursor tokens), and linkHeader (RFC 5988 next links).5. Intelligent Webhook & Async Waiter (api.waitFor())
Purpose-built for waiting on asynchronous events like payment webhooks (Stripe 3DS, Apple Pay, UPI), KYC verification, and background workers:
webhook-waiter.ts
typescript
import { createClient, isWaitForAbortedError } from 'react-native-fetch-client';
const api = createClient({ baseURL: 'https://api.example.com' });
try {
// Mobile app waits for backend webhook worker to finalize order:
const order = await api.waitFor<Order>('/orders/123/status', {
// 1. Success condition:
until: (res) => res.data.status === 'succeeded',
// 2. Fast-abort failure condition (avoids useless polling on rejection):
stopIf: (res) => res.data.status === 'failed',
// 3. Tolerates initial 404s before the webhook worker writes the record:
ignoreErrors: [404],
// 4. Backoff with an interval cap:
interval: 1000,
backoff: 1.5,
maxInterval: 4000, // Capped at 4 seconds
timeout: 45_000, // 45s max total timeout
// 5. Live UI progress callback for spinners:
onTick: ({ attempt, elapsedMs }) => {
console.log(`Checking payment status (attempt ${attempt}, ${Math.round(elapsedMs / 1000)}s)...`);
},
// 6. WHATWG AbortSignal to cancel if user navigates away:
signal: navigationAbortController.signal,
});
console.log('Order verified:', order.data.receiptUrl);
} catch (err) {
if (isWaitForAbortedError(err)) {
console.error('Payment rejected immediately:', err.response.data);
}
}Early Failure Abort (stopIf) & 404 Worker Tolerance
Unlike low-level polling,
api.waitFor() includes a stopIf predicate that immediately fast-fails and throws WaitForAbortedError if a job is rejected. It also tolerates initial 404 Not Found responses (ignoreErrors: [404]) while backend workers insert records.