Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get nextToken working with GET_LIST API call, pagination #11

Open
mayteio opened this issue Mar 18, 2020 · 6 comments
Open

Get nextToken working with GET_LIST API call, pagination #11

mayteio opened this issue Mar 18, 2020 · 6 comments
Assignees
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@mayteio
Copy link
Owner

mayteio commented Mar 18, 2020

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.

@mayteio mayteio self-assigned this Mar 18, 2020
@mayteio mayteio added the enhancement New feature or request label Mar 18, 2020
@mayteio mayteio added the help wanted Extra attention is needed label Mar 24, 2020
@mayteio
Copy link
Owner Author

mayteio commented Mar 24, 2020

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.

@senorgeno
Copy link

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?

@mayteio
Copy link
Owner Author

mayteio commented Apr 28, 2020

👋 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:

// const { nextToken: token } = params.filter || {};
// const nextToken = token && params.pagination.page > 1 ? token : undefined;
// return {
// nextToken,
// };

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
      ...
    }
}

const variables = buildVariablesImpl(introspectionResults)(
resource,
aorFetchType,
params,
queryType
);

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.

@mayteio mayteio added the good first issue Good for newcomers label Apr 30, 2020
@ericluwj
Copy link

ericluwj commented Sep 24, 2020

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.

@mayteio
Copy link
Owner Author

mayteio commented Sep 24, 2020

Unreal, thanks for the info. Have you fixed this in a PR or should I jump in and do it?

@ericluwj
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants