ra-aws-amplify
ra-aws-amplify copied to clipboard
Get nextToken working with GET_LIST API call, pagination
Currently the infrastructure is in place, though the pagination doesn't actually work - just refetches the first 10.
Now nextToken
is stored in redux, it needs to be pulled out in buildVariablesImp
and included in the final variables that get sent to GraphQL.
Struggling with this. When I pass the nextToken
in as a filter and use it in a query, I get an infinite loop that goes from page 1 -> 2 -> 1 -> 2 etc.
Hey, @mayteio great project! It's helping our team scaffold out our project quickly but we are really stuck on this one. Can you help point to where we can look into this one and help? Or is this more of a problem with RA working in with Amplify graphql?
👋 hey @senorgeno, glad you've found it helpful so far. I'd be happy to point you in the right direction.
Firstly, there's a reducer that catches the nextToken
and stores it in redux. You can use it like so:
import { nextTokenReducer } from 'ra-aws-amplify';
export const App = () => (
<Admin ... customReducers={{ nextToken: nextTokenReducer }} />
)
Note: In future release I'd like the API to be import {reducers} from 'ra-aws-amplify'
as while working on many-to-many relationships there are additional reducers we need to pass in, just FYI.
Then, in your list page we have an Amplify Pagination component we can pass in for next/prev instead of having numbers (as DynamoDB doesn't support total records out of the box).
Here's where I'm stuck: I wanted to use permanent filters to pass the nextToken
to the dataProvider
. Permanent filters were the only way to pass arbitrary variables through to the dataProvider
from my research.
import { AmplifyPagination } from 'ra-aws-amplify'
export const PostList = props => {
const nextToken = useSelector(state => state.nextToken);
return <List {...props} pagination={<AmplifyPagination />} filter={{nextToken}} />
}
Note: the use selector could be abstracted into a hook like useNextToken()
so there's minimal cognitive overhead and can be re-used in the <AmplifyPagination />
component.
Problem is, when you actually pass the nextToken
to the API call I am getting a loop that constantly goes from page 1 -> 2 -> 1 -> 2 -> 1 -> etc. Uncomment here:
https://github.com/mayteio/ra-aws-amplify/blob/112dd87fc2b2187266deb01b2b1b73e13ee1e6d0/src/buildAmplifyProvider/buildVariables.ts#L136-L140
The buildGetListVariables
is responsible for building the filter that gets passed to the Amplify GraphQL listPosts
query, for example:
query ListPosts(
$filter: ModelPostFilterInput
$limit: Int
$nextToken: String
) {
listPosts(filter: $filter, limit: $limit, nextToken: $nextToken) {
id
...
}
}
https://github.com/mayteio/ra-aws-amplify/blob/112dd87fc2b2187266deb01b2b1b73e13ee1e6d0/src/buildAmplifyProvider/buildQuery.ts#L36-L41
I don't have time to look at it this week but I am 100% open to collaborating here if you manage to fix it and want to submit a PR for it!
Let me know if I can help or if you have any questions.
import { AmplifyPagination } from 'ra-aws-amplify'
export const PostList = props => {
const nextToken = useSelector(state => state.nextToken);
return <List {...props} pagination={<AmplifyPagination />} filter={{nextToken}} />
}
The nextToken
shouldn't be inserted into the filter directly because then the list will try to reload immediately.
What is desired is to insert nextToken
when the "Next" link is clicked within the pagination component.
Unreal, thanks for the info. Have you fixed this in a PR or should I jump in and do it?
I'm using a quick workaround by doing this:
import { AmplifyPagination } from 'ra-aws-amplify'
export const PostList = props => {
const [nextToken, setNextToken] = useState(null);
return <List {...props} pagination={<AmplifyPagination onNext={(nextToken) => setNextToken(nextToken)} />} filter={{nextToken}} />
}
I also overrided AmplifyPagination
to support onNext
. But it might just be better to create a custom list for Amplify support.
And I think there's also a lot more to be done in ra-aws-amplify/src/buildAmplifyProvider/buildVariables.ts
, to also support number of records per page and filters. So ideally it would be best for you to continue with it.