Reputation: 22731
I've got the following setup for my app. I have a LinkList
component that renders a list of Link
components. Then I also have a CreateLink
component to create new links. Both are rendered under different routes with react-router
:
<Switch>
<Route exact path='/create' component={CreateLink}/>
<Route exact path='/:page' component={LinkList}/>
</Switch>
The Link
type in my GraphQL schema looks as follows:
type Link implements Node {
url: String!
postedBy: User! @relation(name: "UsersLinks")
votes: [Vote!]! @relation(name: "VotesOnLink")
comments: [Comment!]! @relation(name: "CommentsOnLink")
}
I'm using Apollo Client and want to use the imperative store API to update the list after new Link
was created in the CreateLink
component.
await this.props.createLinkMutation({
variables: {
description,
url,
postedById
},
update: (store, { data: { createLink } }) => {
const data = store.readQuery({ query: ALL_LINKS_QUERY }) // ERROR
console.log(`data: `, data)
}
})
The problem is that store.readQuery(...)
throws an error:
proxyConsole.js:56 Error: Can't find field allLinks({}) on object (ROOT_QUERY) {
"allLinks({\"first\":2,\"skip\":10})": [
{
"type": "id",
"id": "Link:cj3ucdguyvzdq0131pzvn37as",
"generated": false
}
],
"_allLinksMeta": {
"type": "id",
"id": "$ROOT_QUERY._allLinksMeta",
"generated": true
}
}.
Here is how I am fetching the list of links in my LinkList
component:
export const ALL_LINKS_QUERY = gql`
query AllLinksQuery($first: Int, $skip: Int) {
allLinks(first: $first, skip: $skip) {
id
url
description
createdAt
postedBy {
id
name
}
votes {
id
}
}
_allLinksMeta {
count
}
}
`
export default graphql(ALL_LINKS_QUERY, {
name: 'allLinksQuery',
options: (ownProps) => {
const { pathname } = ownProps.location
const page = parseInt(pathname.substring(1, pathname.length))
return {
variables: {
skip: (page - 1) * LINKS_PER_PAGE,
first: LINKS_PER_PAGE
},
fetchPolicy: 'network-only'
}
}
}) (LinkList)
I am guessing that the issue somehow has to do with my pagination approach, but I still don't know how to fix it. Can someone point me into the right direction here?
Upvotes: 2
Views: 917
Reputation: 7172
How to read a paginated list from the store depends on how you do the pagination. If you're using fetchMore
, then all the data will be stored under the original keys of the query, which in this case I guess was fetched with { first: 2, skip: 0 }
. That means in order to read the updated list from the store, you would have to use the same parameters, using { first: 2, skip: 0 }
as variables.
PS: The reason Apollo does it this way is because it still allows you to relatively easily update a list via a mutation or update store. If each page was stored separately, it would be very complicated to insert an item in the middle or the beginning of the list, because all of the pages would potentially have to be shifted.
That said, we might introduce a new client-side directive called @connection(name: "ABC")
which would let you explicitly specify under which key the connection is to be stored, instead of automatically storing it under the original variables. Happy to talk more about it if you want to open an issue on Apollo Client.
Upvotes: 2