Gabriel
Gabriel

Reputation: 372

ReactTable v7 - noDataText not showing on empty data (using useTableHook)

I am trying to display some data using the react table v7. It works perfectly using the useTable hook, except it just displays an empty table, without a noDataText as expected.

import React, { useContext, useEffect, useMemo } from 'react'
import {
    useTable,
    useSortBy,
    useFilters,
    usePagination,
} from 'react-table'
import '../css/datatable.css'
import WarehouseAction from './WarehouseAction'
import { WarehouseContext } from '../context/WarehouseContext'
import { AuthContext } from '../context/AuthContext'
import AddStock from './AddStock'
import { Filter, DefaultColumnFilter } from './Filter'
import { InlineIcon } from '@iconify/react'
import ChevronCircleUp from '@iconify/icons-jam/chevron-circle-up'
import ChevronCircleDown from '@iconify/icons-jam/chevron-circle-down'






function WarehouseData() {

    const { warehouseData, getWarehouseRequest } = useContext(WarehouseContext)
    const { profile } = useContext(AuthContext)


    useEffect(() => {
        getWarehouseRequest()
    },[])


    
    const data = useMemo(() => [...warehouseData],[warehouseData])
    
    const columns = useMemo(() => [
        { Header: 'Stock', accessor: 'stock', disableSortBy: true, },
        { Header: 'Description', accessor: 'description', disableSortBy: true},
        { Header: 'Price', accessor: 'unit_price', disableFilters: true},
        { 
            Header: 'Total', accessor: 'units_total',
            Cell: ({cell}) => {
                if (cell.row.values.units_total === 0){
                    return <p style={{ color: '#f00'}}>Out of Stock</p>
                } else if (cell.row.values.units_total < 5){
                    return <p style={{ color: '#ffa600'}}>{cell.row.values.units_total}</p>
                } else {
                    return <p style={{ color: '#090'}}>{cell.row.values.units_total}</p>
                }
            },
            disableFilters: true,
        },
        { Header: 'Updated', accessor: 'record_updated', disableFilters: true},
        { 
            Header: 'Action', accessor: 'id',
            Cell: ({cell}) => (
                <WarehouseAction key={cell.row.values.id}
                    id={cell.row.values.id} 
                    stock={cell.row.values.stock} 
                    description={cell.row.values.description} 
                    price={cell.row.values.unit_price} 
                    total={cell.row.values.units_total} 
                    updated={cell.row.values.record_updated} 
                />
            ),
            disableSortBy: true,
            disableFilters: true,
        },
    ], [])


    const generateSortingIndicator = column => {
        return column.isSorted ? 
            (column.isSortedDesc) ?
                <InlineIcon className="inline-icon" icon={ChevronCircleDown} />
                : <InlineIcon className="inline-icon" icon={ChevronCircleUp} />
                : ""
    }


    const onChangeInSelect = event => {
        setPageSize(Number(event.target.value))
    }

    const onChangeInInput = event => {
        const page = event.target.value ? Number(event.target.value) -1 : 0
        gotoPage(page)
    }


    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        // rows,
        page,
        prepareRow,
        canPreviousPage,
        canNextPage,
        pageOptions,
        pageCount,
        gotoPage,
        nextPage,
        previousPage,
        setPageSize,
        state: { pageIndex, pageSize }
    } = useTable(
        { 
            columns, 
            data, 
            defaultColumn: { Filter: DefaultColumnFilter },
            initialState: { pageIndex: 0, pageSize: 5}
        },
            useFilters,
            useSortBy,
            usePagination,
        )


    return (
        <React.Fragment>
            <div className="table-top">    
                { profile.is_admin && (<AddStock mode={"WAREHOUSE"}/> )}
            </div>
            <table {...getTableProps()}>
                <thead>
                    {headerGroups.map(headerGroup => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map(column => (
                                <th {...column.getHeaderProps()}>
                                    <div {...column.getHeaderProps(column.getSortByToggleProps())}>
                                        {column.render('Header')}
                                        {generateSortingIndicator(column)}
                                    </div>
                                    <Filter column={column} />
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>

                <tbody {...getTableBodyProps()}>
                    {page.map( row => {
                        prepareRow(row)
                        return(
                            <tr {...row.getRowProps()}>
                                {row.cells.map(cell => {
                                    return (
                                        <td {...cell.getCellProps()}>
                                            {cell.render('Cell')}
                                        </td>
                                    )
                                })}
                            </tr>
                        )
                    })}
                </tbody>
            </table>

            <ul id="pagination">
                <li className="page-item" onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
                    First
                </li>
                <li className="page-item" onClick={() => previousPage()} disabled={!canPreviousPage}>
                    {'<'}
                </li>
                <li className="page-count">
                    <strong>
                        {pageIndex + 1}
                    </strong>
                </li>
                <li className="page-item" onClick={() => nextPage()} disabled={!canNextPage}>
                    {'>'}
                </li>
                <li className="page-item" onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
                    Last
                </li>
                <li className="page-input">
                    <input
                        type="number"
                        defaultValue={pageIndex + 1}
                        min={1}
                        max={pageOptions.length}
                        onChange={onChangeInInput}
                        />
                </li>
                <select
                    value={pageSize}
                    className="page-select"
                    onChange={onChangeInSelect}>
                        <option key={pageSize} value={pageSize}>
                            Show {pageSize}
                        </option>
                </select>
            </ul>
        </React.Fragment>
    )
}

export default WarehouseData

enter image description here

Here is a visual of what the table looks like without data. How can I get reactTable (using usetable hook) to display a "no data" text when it's empty, and possibly a "loading" text when fetching data.

Upvotes: 4

Views: 9212

Answers (1)

Tom
Tom

Reputation: 6709

You are calling map on page for each row.

So before that you could just check to see of page doesn't contain any rows, and return an appropriate message.

Eg:

{(
page.length > 0 && page.map( row => { ....... 

) || <span>no data....</span>}

Upvotes: 6

Related Questions