Skip to content

Before & after cursor not behaving correctly #77

Open
@acSpock

Description

@acSpock

I'm puzzled. How is this behavior supposed to work?

current version: 0.10.1

Here's my API response fetching a table with only 18 items in the table:

api/resource?limit=10

{
   data: [10 records...]
   beforeCursor: null,
   afterCursor: 'Y3JlYXRlZEF0OjE2Nzc5NjQ1NDg3NzksaWQ6ZDQ5YzA3NjgtNTBlYy00M2I3LWExNzctYjAxNmQ2YjE3YjRm'
}

so far so good. let's move forward:

api/resource?limit=10&afterCursor=Y3JlYXRlZEF0OjE2Nzc5NjQ1NDg3NzksaWQ6ZDQ5YzA3NjgtNTBlYy00M2I3LWExNzctYjAxNmQ2YjE3YjRm

{
   data: [8 records...]
   beforeCursor: 'Y3JlYXRlZEF0OjE2Nzc4MDgzODM1NjgsaWQ6NmYxNGRmZDEtOGQ1Zi00OTZlLTkzZmUtOTc3MDkzMDY5YzAw',
   afterCursor: null
}

still... so far so good. Let's go back

api/resource?limit=10&beforeCursor=Y3JlYXRlZEF0OjE2Nzc4MDgzODM1NjgsaWQ6NmYxNGRmZDEtOGQ1Zi00OTZlLTkzZmUtOTc3MDkzMDY5YzAw

{
   data: [10 records...]
    "afterCursor": "Y3JlYXRlZEF0OjE2Nzc4MDgzODM1NjgsaWQ6NmYxNGRmZDEtOGQ1Zi00OTZlLTkzZmUtOTc3MDkzMDY5YzAw",
    "beforeCursor": "Y3JlYXRlZEF0OjE2Nzg1NzY0MTM3NzcsaWQ6ZTdiZDhkMGEtODkyMi00MDM4LTlhZTEtMWMwYzMxYjhkNGJl",
}

mmmm that's a little strange. Data is right, but I'm seeing a beforeCursor again. There shouldn't be, because aren't we back at the beginning of the list?

Let's try going forward 1 more time.

api/resource?limit=10&afterCursor=Y3JlYXRlZEF0OjE2Nzc4MDgzODM1NjgsaWQ6NmYxNGRmZDEtOGQ1Zi00OTZlLTkzZmUtOTc3MDkzMDY5YzAw

{
   data: [7 records]
    "afterCursor": "",
    "beforeCursor": "Y3JlYXRlZEF0OjE2Nzc4MDY5NTY0NTMsaWQ6NjI2NWY2YzItOGQwYS00MGU4LWIwYmItYjAxNzIwODQwMWUy",
}

That's not right. 7 records.

And if I keep going back and forth, I'll go back to 10 records then if I go forward again, 6 records, then back to 10 records then forward to 5 until it goes down to 0.

Why?

Here's my implementation:

  async queryData(userId: string, beforeCursor: string | undefined, afterCursor: string | undefined, limit: number, order = 'DESC'): Promise<{ data: Response[], afterCursor: string | null, beforeCursor: string | null, totalCount: number }> {
    const totalCount = await this.entityManager.createQueryBuilder(TestEntity, 'test')
      .where('test.userId = :userId', { userId })
      .getCount();

    const queryBuilder = this.entityManager.getRepository(TestEntity).createQueryBuilder('test')
      .where('test.userId = :userId', { userId })
      .take(limit);

    const paginator = buildPaginator({
      entity: TestEntity,
      alias: 'test',
      paginationKeys: ['createdAt', 'id'],
      query: {
        order: 'DESC',
      },
    });

    if (afterCursor) {
      paginator.setAfterCursor(afterCursor);
    } else if (beforeCursor) {
      paginator.setBeforeCursor(beforeCursor);
    }

    paginator.setLimit(limit);

    const { data: testResults, cursor: cursorResult } = await paginator.paginate(queryBuilder);

    return {
      testResults,
      afterCursor: cursorResult.afterCursor,
      beforeCursor: cursorResult.beforeCursor,
      totalCount,
    };
  }

I'm experimenting with cursor pagination and fastify and i'm wondering why this behavior is happening. Any help would be appreciative.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions