Skip to content

Instantly share code, notes, and snippets.

@andyrichardson
Created April 12, 2021 12:39
Show Gist options
  • Save andyrichardson/d007dba71797636ebd977c7f362f9e2d to your computer and use it in GitHub Desktop.
Save andyrichardson/d007dba71797636ebd977c7f362f9e2d to your computer and use it in GitHub Desktop.

Unidirectional pagination

const paginateQuery = async <T>({
    params,
    acc = [],
    pageSize,
  }: {
    params: DynamoDB.DocumentClient.QueryInput;
    acc?: T[];
    pageSize: number;
  }): Promise<{ page: T[]; hasNextPage: boolean }> => {
    const remaining = pageSize - acc.length;
    const result = await client.query(params).promise();
    const newAcc = [...acc, ...((result.Items?.slice(0, remaining) || []) as T[])];
    
    // Query exhausted
    if (!result.LastEvaluatedKey || !result.Items) {
      return {
        page: newAcc,
        hasNextPage: false,
      }
    }
    
    if (
      // Page needs to be filled more
      newAcc.length < pageSize ||
      // Page is filled but hasNextPage is unknown
      result.Items.length <= remaining
    ) {
      return paginateQuery({
        params: {
          ...params,
          ExclusiveStartKey: result.LastEvaluatedKey,
        },
        acc: newAcc,
        pageSize,
      });
    }

    return {
      page: newAcc,
      hasNextPage: true,
    };
  };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment