Open Nightbr opened 3 years ago
@Nightbr Can you share the (relevant parts of the) query you're using? I'm wondering how exactly you're consuming the variables.paging
variable when you use the Query.myObjects
field in your query, because those field arguments are what the relayStylePagination
policy ends up seeing.
In case this is helpful, it looks like your Apollo Client URLs are still referring to the master
branch—we switched to main
last August, around the time of @apollo/client@3.1.4
(though what's published to npm shouldn't be affected by branch names). I mention this mostly because the relayStylePagination
helper has seen a number of improvements since then.
Override relayStylePagination merge method to flatten paging object at root and pass args.after & args.before
This is always an option, either by starting with relayStylePagination()
and wrapping its read
and merge
methods, or by copy/pasting the relayStylePagination
code and reimplementing how it uses args
. Nothing wrong with that! The pagination helpers are primarily intended as inspiration for your own policy helpers, not necessarily for direct reuse (especially if you're going off the beaten path, which you seem to be doing here).
@benjamn Hey thanks for your complete answer!!
I got the latest code from main branch, thanks for pointing this :ok_hand: -> https://github.com/apollographql/apollo-client/blob/main/src/utilities/policies/pagination.ts
Here is my gql
query myObjectsQuery($filter: MyObjectFilter, $paging: CursorPaging, $sorting: [MyObjectSort!]) {
myObjects(filter: $filter, paging: $paging, sorting: $sorting) {
edges {
cursor
node {
createdAt
id
name
status
updatedAt
workspaceId
}
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
}
and CursorPaging type:
export type CursorPaging = {
/** Paginate after opaque cursor */
after?: Maybe<Scalars['ConnectionCursor']>;
/** Paginate before opaque cursor */
before?: Maybe<Scalars['ConnectionCursor']>;
/** Paginate first */
first?: Maybe<Scalars['Int']>;
/** Paginate last */
last?: Maybe<Scalars['Int']>;
};
Everything else respects the Relay pagination convention.
But yes, like you said, I have Copy/Paste the relayStylePagination
and handle my own version. Perhaps I will create a lib with some utilities with this and the settings to configure where to find after
& before
args.
This used to work and I think the updates broke that unsupported? functionality.
Ran into this exact issue today where the pagination arguments were inside a variable and the relayStylePagination
function wouldn't work properly.
Is the apollo team open to making a change to the relayStylePagination
to accept an additional argument for where the pagination variables are located?
I use apollo-cursor-pagination and the following typeDefs: https://github.com/FleekHQ/apollo-cursor-pagination/blob/master/tests/test-app/src/type-defs/cat.js
With the change of the pagination variables being placed in an input type.
E.g.
"Input for Pagination"
input PaginationInput {
"Slice from the back"
first: Int
"After the cursor"
after: String
"Slice from the front"
last: Int
"Before the cursor"
before: String
"Order by column"
orderBy: String
"Order by direction"
orderDirection: OrderDirection
"Multiple order by directions"
orderDirectionMultiple: [OrderDirection]
"Multiple order by columns"
orderByMultiple: [String!]
"Whether to use Offset Pagination"
useOffsetPagination: Boolean
}
If I didn't do this, I'll have to be introducing duplicate pagination args for every single query that I want paginated.
e.g.
offersByUserConnection(input: PaginationInput): OffersConnection!
offersConnection(input: PaginationInput): OffersConnection!
allOffersConnection(input: PaginationInput): OffersConnection!
would become
offersByUserConnection(first: Int, after: String, last: Int, before: String, orderBy: String, orderDirection: OrderDirection, orderDirectionMultiple: [OrderDirection], orderByMultiple: [String!], useOffsetPagination: Boolean)
offersConnection(first: Int, after: String, last: Int, before: String, orderBy: String, orderDirection: OrderDirection, orderDirectionMultiple: [OrderDirection], orderByMultiple: [String!], useOffsetPagination: Boolean)
allOffersConnection(first: Int, after: String, last: Int, before: String, orderBy: String, orderDirection: OrderDirection, orderDirectionMultiple: [OrderDirection], orderByMultiple: [String!], useOffsetPagination: Boolean)
From what I've read, there doesn't seem to be a way to define a set of arguments and reuse them other than the above approach.
Thoughts?
I solved the issue by just modifying the lines with patch-package
:
to
if (args && args.after || args && args.input && args.input.after) {
const after = args.after || args.input.after;
var index = prefix.findIndex(function (edge) { return edge.cursor === after; });
if (args && args.before || args && args.input && args.input.before) {
const before = args.before || args.input.before;
var index = prefix.findIndex(function (edge) { return edge.cursor === before; });
Since this still hasn't gotten a response from the apollo team, utilities.cjs.native.js
was added and I had to patch that file too.
This is my patch-package
file for @apollo/client:3.6.8
@apollo+client+3.6.8.patch
diff --git a/node_modules/@apollo/client/utilities/policies/pagination.js b/node_modules/@apollo/client/utilities/policies/pagination.js
index bdf7b9f..76cb888 100644
--- a/node_modules/@apollo/client/utilities/policies/pagination.js
+++ b/node_modules/@apollo/client/utilities/policies/pagination.js
@@ -99,14 +99,16 @@ export function relayStylePagination(keyArgs) {
}
var prefix = existing.edges;
var suffix = [];
- if (args && args.after) {
- var index = prefix.findIndex(function (edge) { return edge.cursor === args.after; });
+ if (args && args.after || args && args.input && args.input.after) {
+ const after = args.after || args.input.after;
+ var index = prefix.findIndex(function (edge) { return edge.cursor === after; });
if (index >= 0) {
prefix = prefix.slice(0, index + 1);
}
}
- else if (args && args.before) {
- var index = prefix.findIndex(function (edge) { return edge.cursor === args.before; });
+ else if (args && args.before || args && args.input && args.input.before) {
+ const before = args.before || args.input.before;
+ var index = prefix.findIndex(function (edge) { return edge.cursor === before; });
suffix = index < 0 ? prefix : prefix.slice(index);
prefix = [];
}
diff --git a/node_modules/@apollo/client/utilities/utilities.cjs b/node_modules/@apollo/client/utilities/utilities.cjs
index 817f777..3b6cde8 100644
--- a/node_modules/@apollo/client/utilities/utilities.cjs
+++ b/node_modules/@apollo/client/utilities/utilities.cjs
@@ -847,14 +847,16 @@ function relayStylePagination(keyArgs) {
}
var prefix = existing.edges;
var suffix = [];
- if (args && args.after) {
- var index = prefix.findIndex(function (edge) { return edge.cursor === args.after; });
+ if (args && args.after || args && args.input && args.input.after) {
+ const after = args.after || args.input.after;
+ var index = prefix.findIndex(function (edge) { return edge.cursor === after; });
if (index >= 0) {
prefix = prefix.slice(0, index + 1);
}
}
- else if (args && args.before) {
- var index = prefix.findIndex(function (edge) { return edge.cursor === args.before; });
+ else if (args && args.before || args && args.input && args.input.before) {
+ const before = args.before || args.input.before;
+ var index = prefix.findIndex(function (edge) { return edge.cursor === before; });
suffix = index < 0 ? prefix : prefix.slice(index);
prefix = [];
}
diff --git a/node_modules/@apollo/client/utilities/utilities.cjs.native.js b/node_modules/@apollo/client/utilities/utilities.cjs.native.js
index 817f777..3b6cde8 100644
--- a/node_modules/@apollo/client/utilities/utilities.cjs.native.js
+++ b/node_modules/@apollo/client/utilities/utilities.cjs.native.js
@@ -847,14 +847,16 @@ function relayStylePagination(keyArgs) {
}
var prefix = existing.edges;
var suffix = [];
- if (args && args.after) {
- var index = prefix.findIndex(function (edge) { return edge.cursor === args.after; });
+ if (args && args.after || args && args.input && args.input.after) {
+ const after = args.after || args.input.after;
+ var index = prefix.findIndex(function (edge) { return edge.cursor === after; });
if (index >= 0) {
prefix = prefix.slice(0, index + 1);
}
}
- else if (args && args.before) {
- var index = prefix.findIndex(function (edge) { return edge.cursor === args.before; });
+ else if (args && args.before || args && args.input && args.input.before) {
+ const before = args.before || args.input.before;
+ var index = prefix.findIndex(function (edge) { return edge.cursor === before; });
suffix = index < 0 ? prefix : prefix.slice(index);
prefix = [];
}
Is there any updates on this one?
Hey folks, I ran into an issue with relayStylePagination and nestjs-query because in NestJs query all pagination params are in
paging
object.See more here.
Intended outcome:
When calling
fetchMore
the next results should append to the existing set of data.Actual outcome:
When calling
fetchMore
, the next results override the existing set of data.How to reproduce the issue:
Here is my InMemoryCache configuration:
Here is my page component:
You can see that in
fetchMore
, pagination params are in apaging
object.And if we look at the relayStylePagination code:
https://github.com/apollographql/apollo-client/blob/master/src/utilities/policies/pagination.ts#L93
We can see it gets args
after
&before
only if they are at root of args (which is not the case). So we go to the else and it replace the existing edges.Here is another comment which talk about this issue -> https://github.com/apollographql/apollo-client/issues/6502#issuecomment-869053815
Possible solutions
relayStylePagination
merge method to flatten paging object at root and pass args.after & args.beforerelayStylePagination
with the path to the paging object (after, before) by default it's args root.Versions
Thanks for your help, feel free to ask anything and if you're ok with a solution, I can make a PR :ok_hand:
Cheers!