twilio / frontline-demo-service

MIT License
16 stars 36 forks source link

get customer list - pagination and list size #2

Open neowashumanizedcode opened 2 years ago

neowashumanizedcode commented 2 years ago

Hi Guys,

When I get my customer list using providers/customers, my api returns lists of multiple customers for one of my users where the results are paginated. If I dont process the paginated results, only the 1st page is available, if I process the paginated results (which is what I currently do) i have issues with the search function in Frontline and if I load up to 700 clients for one of my users, the getCustomerList times out.

Since it's only refreshed the first time its loaded or if manually refreshed, cant you allow for more time to return results please?

Regards,

Gary

askel4dd commented 2 years ago

@neowashumanizedcode Unfortunately we can't increase the timeout time, and currently it's a bit less than 7 seconds. You can use Frontline pagination feature instead so you dont need to load the whole 700 clients list all at once and only return a certain page. On this doc page you can see GetCustomersList parameters and one of them is NextPageToken and PageSize. These two you can use to paginate users in Frontline, for example: your API returns back you a paginated result of customers and most probably every page in the result has it's page token or something like this, so If you would return us that next page token in the response like this: objects.next_page_token: <page token> and the next time mobile App will call your API it will use that token, so you can return next page. This way you can return data faster and solve timeouts issue.

Example code. Keep in mind that I dont know all the details about the API that you are using and how the pagination is working in it.

const handleGetCustomersListCallback = async (req, res) => {
    console.log('Getting Customers list');

    const body = req.body;
    const workerIdentity = req.body.Worker;
    const pageSize = body.PageSize;
    const anchor = body.Anchor;
    const nextPageToken = body.NextPageToken;

    // Fetch Customers list based on information about a worker, that requested it
    const customersPage = await getCustomersList(workerIdentity, pageSize, anchor, nextPageToken);

    // Respond with Customers object
    res.send({
        objects: {
            customers: customersPage.items,
            next_page_token: customersPage.next_page_token,
        }
    });
};
neowashumanizedcode commented 2 years ago

Hi @askel4dd - I changed the code so we only load each list returned in the initial results and pass a pagination token that is fead back into the query when you scroll to the bottom.

This helps with large lists as well so that we're only ever processing 1 page at a time.

I noted a problem though. The getCustomerList logic either

List the initial set of results

OR

processes the paginated results.

When this hits the last page, it returns the first page results again.

When you use the search function, it continuously cycles through the pages and when it starts at the beginning, it keeps adding a new entry for the same customer to the search results.

How do I stop it from running through all the pages again?

askel4dd commented 2 years ago

@neowashumanizedcode

How do I stop it from running through all the pages again?

You should be able to stop that by returning an empty customers list when user has reached, that will stop the App from making any further requests. If that wont be enough, that means that we have a bug in the App, in that case you can also return nextPageToken as end or something like this, so you can check it and immediately return empty list.

When you use the search function, it continuously cycles through the pages and when it starts at the beginning, it keeps adding a new entry for the same customer to the search results.

About the search. We have implemented two ways to search customers:

  1. If your Integration Service will return us searchable flag set to true we wont traverse the whole list, instead we will implying that your service will do the search and will respond us back with the paginated list of filtered customers, in the same manner as the usual story of scrolling the list, but this time use Query request parameter for filtering.

  2. Now, if you wont return us searchable flag set to true we will do the search our self by traversing through your list of customers and then filtering then in the App.

In the search case and the simple scrolling case you should be able to stop the App by returning us an empty list.

neowashumanizedcode commented 2 years ago

The issue here is that nextPageToken returns nothing on the 1st search since there's only a value after the first search. If I return an empty list if nextPageToken = undefined, no clients will be listed since this is true for the first search as well as if I've searched through multiple pages and get to the last page

I cant use Anchor since I'm using the next page logic and would need to cycle through all the pages to check if Anchor matched the last client which times out.

I do know exactly how many clients are on the search results so if I have a value that incrementally counts the number of clients loaded and the total number loaded = total number of clients, it should stop.