Help

Paginate records programmatically

Topic Labels: Extensions
Solved
Jump to Solution
2348 3
cancel
Showing results for 
Search instead for 
Did you mean: 
Fredrick_Esedo
5 - Automation Enthusiast
5 - Automation Enthusiast

The code below successfully display records. Please how do I add pagination to it. Thanks

  const base = useBase();
    const table = base.getTableByNameIfExists('myfirst_table');
     // grab all the records from that table
     const records = useRecords(table);
     // render a list of records:
     return (
         <ul>
             {records.map(record => {
                 return <li key={record.id}>{record.id} -- {record.getCellValueAsString('lastname')}</li>
             })}
         </ul>
     );
1 Solution

Accepted Solutions
Rebecca_Meritz
5 - Automation Enthusiast
5 - Automation Enthusiast

None of the APIs provided by Airtable provide a method to get only a subset of records from a query at a time, so if you wanted pagination to limit the amount of data you are pulling at one time for performance reasons it is not currently possible.

Airtable’s UI doesn’t currently provide any way to add pagination purely to the UI either, but you could roll your own or use any npm package that provides pagination.

I wrote a little example that uses react-js-paginate to paginate records.

/*
The MIT-Zero License

Copyright (c) 2020 Bocoup

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

import {
    initializeBlock,
    useBase,
    useRecords,
} from '@airtable/blocks/ui';
import React, { useState } from 'react';
import Pagination from "react-js-pagination";

function Block() {
    const base = useBase();
    const table = base.getTableByNameIfExists('myfirst_table');
    const records = useRecords(table);
    const itemCountPerPage = 10;
    const [activePage, setActivePage] = useState(1);
    const sliceRecords = () => {
      const limit = (itemCountPerPage * activePage);
      return records.slice(limit - itemCountPerPage, limit);
    };
    const [offsetRecords, setOffsetRecords] = useState(sliceRecords());
    const handleChange = (pageNumber) => {
      setActivePage(pageNumber);
      setOffsetRecords(sliceRecords());
    }

    return (
      <div>
        <ul>
          {offsetRecords.map(record => {
            return <li key={record.id}>{record.id} -- {record.getCellValueAsString('lastname')}</li>
          })}
        </ul>

        <Pagination
          activePage={activePage}
          itemsCountPerPage={itemCountPerPage}
          totalItemsCount={records.length}
          onChange={handleChange}
        />
      </div>
    );
}

initializeBlock(() => <Block />);

See Solution in Thread

3 Replies 3
Fredrick_Esedo
5 - Automation Enthusiast
5 - Automation Enthusiast

hello @Kamille_Parks, any help please

Rebecca_Meritz
5 - Automation Enthusiast
5 - Automation Enthusiast

None of the APIs provided by Airtable provide a method to get only a subset of records from a query at a time, so if you wanted pagination to limit the amount of data you are pulling at one time for performance reasons it is not currently possible.

Airtable’s UI doesn’t currently provide any way to add pagination purely to the UI either, but you could roll your own or use any npm package that provides pagination.

I wrote a little example that uses react-js-paginate to paginate records.

/*
The MIT-Zero License

Copyright (c) 2020 Bocoup

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

import {
    initializeBlock,
    useBase,
    useRecords,
} from '@airtable/blocks/ui';
import React, { useState } from 'react';
import Pagination from "react-js-pagination";

function Block() {
    const base = useBase();
    const table = base.getTableByNameIfExists('myfirst_table');
    const records = useRecords(table);
    const itemCountPerPage = 10;
    const [activePage, setActivePage] = useState(1);
    const sliceRecords = () => {
      const limit = (itemCountPerPage * activePage);
      return records.slice(limit - itemCountPerPage, limit);
    };
    const [offsetRecords, setOffsetRecords] = useState(sliceRecords());
    const handleChange = (pageNumber) => {
      setActivePage(pageNumber);
      setOffsetRecords(sliceRecords());
    }

    return (
      <div>
        <ul>
          {offsetRecords.map(record => {
            return <li key={record.id}>{record.id} -- {record.getCellValueAsString('lastname')}</li>
          })}
        </ul>

        <Pagination
          activePage={activePage}
          itemsCountPerPage={itemCountPerPage}
          totalItemsCount={records.length}
          onChange={handleChange}
        />
      </div>
    );
}

initializeBlock(() => <Block />);

Thanks alot @Rebecca_Meritz