Skip to content

entries.paginate()

Automatically paginate through all entries in a feed using async iteration.

Signature

entries.paginate(feedId: string, options?: PaginateEntriesOptions): AsyncGenerator<Entry, void, unknown>

Parameters

feedId

  • Type: string
  • Required: Yes
  • Description: The UUID of the feed to paginate entries from

options

  • Type: PaginateEntriesOptions (optional)
interface PaginateEntriesOptions {
  limit?: number;        // Items per page (default: 50)
  tags?: string[];       // Filter by tags
  is_free?: boolean;     // Filter free/paid entries
  sort?: 'created_at' | 'title';
  order?: 'asc' | 'desc';
}

Returns

  • Type: AsyncGenerator<Entry, void, unknown>

Returns an async generator that yields individual Entry objects.

Usage

Basic Example

// Iterate through all entries
for await (const entry of grapevine.entries.paginate(feedId)) {
  console.log(entry.title || 'Untitled');
}

With Filters

// Paginate through free entries only
for await (const entry of grapevine.entries.paginate(feedId, {
  is_free: true,
  sort: 'created_at',
  order: 'desc'
})) {
  console.log(`Free: ${entry.title}`);
}

Process Tagged Entries

// Process entries with specific tags
for await (const entry of grapevine.entries.paginate(feedId, {
  tags: ['analysis', 'premium']
})) {
  await processAnalysis(entry);
}

Collect All Results

// Collect all entries into array
async function getAllEntries(feedId: string) {
  const allEntries: Entry[] = [];
  
  for await (const entry of grapevine.entries.paginate(feedId)) {
    allEntries.push(entry);
  }
  
  return allEntries;
}
 
// Or using Array.fromAsync
const allEntries = await Array.fromAsync(
  grapevine.entries.paginate(feedId)
);

Early Termination

// Stop after finding specific entry
async function findEntry(feedId: string, searchTitle: string) {
  for await (const entry of grapevine.entries.paginate(feedId)) {
    if (entry.title?.includes(searchTitle)) {
      return entry; // Stops iteration
    }
  }
  return null;
}

Export to Different Format

// Export entries to CSV
async function exportToCSV(feedId: string) {
  const csv: string[] = ['Title,Content,Tags,Created,Free'];
  
  for await (const entry of grapevine.entries.paginate(feedId)) {
    const row = [
      entry.title || '',
      entry.content.substring(0, 100),
      entry.tags.join(';'),
      new Date(entry.created_at * 1000).toISOString(),
      entry.is_free ? 'Yes' : 'No'
    ].map(field => `"${field}"`).join(',');
    
    csv.push(row);
  }
  
  return csv.join('\n');
}

Process in Batches

async function processBatches(feedId: string) {
  const batch: Entry[] = [];
  const batchSize = 10;
  
  for await (const entry of grapevine.entries.paginate(feedId)) {
    batch.push(entry);
    
    if (batch.length === batchSize) {
      await processBatch(batch);
      batch.length = 0; // Clear batch
    }
  }
  
  // Process remaining entries
  if (batch.length > 0) {
    await processBatch(batch);
  }
}

With Progress Tracking

async function paginateWithProgress(feedId: string) {
  let count = 0;
  let freeCount = 0;
  let paidCount = 0;
  
  for await (const entry of grapevine.entries.paginate(feedId, {
    limit: 25
  })) {
    count++;
    
    if (entry.is_free) {
      freeCount++;
    } else {
      paidCount++;
    }
    
    if (count % 10 === 0) {
      console.log(`Processed ${count} entries (${freeCount} free, ${paidCount} paid)`);
    }
    
    await processEntry(entry);
  }
  
  console.log(`Total: ${count} entries (${freeCount} free, ${paidCount} paid)`);
}

Behind the Scenes

This method:

  1. Makes initial request to get first page
  2. Yields entries one by one from current page
  3. Automatically fetches next page when needed
  4. Continues until no more pages available
  5. Handles pagination state internally
  6. Respects authentication for content access

Error Handling

try {
  for await (const entry of grapevine.entries.paginate(feedId)) {
    console.log(entry.title);
  }
} catch (error) {
  console.error('Pagination error:', error);
}
 
// With individual error handling
async function safePaginate(feedId: string) {
  try {
    for await (const entry of grapevine.entries.paginate(feedId)) {
      try {
        await processEntry(entry);
      } catch (entryError) {
        console.error(`Error processing ${entry.id}:`, entryError);
        // Continue with next entry
      }
    }
  } catch (paginationError) {
    console.error('Pagination failed:', paginationError);
  }
}

Notes

  • Memory Efficient: Yields one entry at a time
  • Automatic: Handles page fetching automatically
  • Lazy Loading: Only fetches pages as needed
  • Interruptible: Can break/return early to stop iteration
  • Authentication: Respects auth for content visibility
  • Content Access: Free entries show full content, paid entries require purchase

Related