Troubleshooting
Common issues and their solutions
Troubleshooting Guide
Solutions to common issues you might encounter while using the Advanced Data Table Component.
Table Not Displaying Data
Issue: Table shows "No results" but API returns data
Possible Causes:
- Schema validation failing
- Incorrect data structure
- Missing required fields
Solution:
Check API Response
Open browser DevTools → Network tab and inspect the API response:
{
"success": true,
"data": [...], // ✅ Data exists
"pagination": {...}
}Validate with Zod Schema
Ensure your schema matches the API response:
// If API returns snake_case
export const userSchema = z.object({
id: z.number(),
user_name: z.string(), // ✅ Match API format
created_at: z.string(),
});
// If API returns camelCase
export const userSchema = z.object({
id: z.number(),
userName: z.string(), // ✅ Match API format
createdAt: z.string(),
});Check Console Errors
Look for Zod validation errors in the console:
Error: Invalid type received for field "userName"
Expected: string, Received: undefinedThis means your API returns a different field name than your schema expects.
Table Not Updating After Mutations
Issue: Table doesn't refresh after add/delete/update
Possible Causes:
- React Query cache not invalidated
- Missing
router.refresh()call
Solution:
const handleDelete = async (id: number) => {
try {
const response = await deleteUser(id);
if (response.success) {
toast.success("User deleted");
// ✅ Solution 1: Invalidate React Query cache
await queryClient.invalidateQueries({ queryKey: ["users"] });
// ✅ Solution 2: Refresh the page (Next.js)
router.refresh();
}
} catch (error) {
toast.error("Failed to delete");
}
};Row Selection Not Working
Issue: Checkboxes don't appear or selection doesn't work
Possible Causes:
enableRowSelectionnot set- Missing
handleRowDeselectionin columns - Incorrect column structure
Solution:
Enable Row Selection
config={{
enableRowSelection: true, // ✅ Enable this
}}Add Selection Column
const getColumns = (handleRowDeselection) => {
// ✅ Check handleRowDeselection is not null
if (handleRowDeselection !== null) {
return [
{
id: "select",
header: ({ table }) => (
<Checkbox
checked={table.getIsAllPageRowsSelected()}
onCheckedChange={(value) =>
table.toggleAllPageRowsSelected(!!value)
}
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
/>
),
enableSorting: false,
enableHiding: false,
},
...baseColumns,
];
}
return baseColumns;
};Export Not Working
Issue: Export button missing or export fails
Possible Causes:
- Missing
exportConfigprop - Incorrect column mapping
- Transform function errors
Solution:
Add Export Config
<DataTable
exportConfig={useExportConfig()} // ✅ Add this
// ... other props
/>Verify Export Configuration
export function useExportConfig() {
return {
headers: ["id", "name", "email"], // ✅ Must match data fields
columnMapping: {
id: "ID",
name: "Name",
email: "Email",
},
entityName: "users", // ✅ Required for filename
};
}Check Transform Function
If using a transform function, ensure it doesn't throw errors:
transformFunction: (row) => {
try {
return {
...row,
created_at: formatDate(row.created_at), // ✅ Handle null/undefined
};
} catch (error) {
console.error("Transform error:", error);
return row; // Return original on error
}
}Sorting Not Working
Issue: Clicking column headers doesn't sort
Possible Causes:
- Server not handling sort parameters
- Incorrect column
accessorKey enableSortingset tofalse
Solution:
Check Server Implementation
Ensure your API handles sort_by and sort_order parameters:
// API should receive and use these params
const sortBy = req.query.sort_by; // e.g., "name"
const sortOrder = req.query.sort_order; // e.g., "asc"
query = query.orderBy(sortBy, sortOrder);Verify Column Definition
{
accessorKey: "name", // ✅ Must match data field
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Name" />
),
enableSorting: true, // ✅ Enable sorting
}Check Default Sort Configuration
config={{
defaultSortBy: "created_at", // ✅ Must match column accessorKey
defaultSortOrder: "desc",
}}Search Not Working
Issue: Typing in search doesn't filter results
Possible Causes:
- Server not implementing search
- Search debounce delay
- API error
Solution:
Verify Server Handles Search
// API must handle 'search' parameter
const search = req.query.search || '';
if (search) {
query = query.where((builder) => {
builder
.where('name', 'ilike', `%${search}%`)
.orWhere('email', 'ilike', `%${search}%`);
});
}Check Network Tab
Search requests are debounced (300ms delay):
- Type in search box
- Wait 300ms
- Check Network tab for API request with
searchparameter
Enable Search
config={{
enableSearch: true, // ✅ Must be enabled
}}Subrows Not Expanding
Issue: Expand icon doesn't show or rows don't expand
Possible Causes:
- Missing
subRowsConfig - No
subRowsarray in data ExpandIconnot added to columns
Solution:
Enable Subrows
subRowsConfig={{
enabled: true,
mode: 'same-columns',
expandIconPosition: 'first',
}}Verify Data Structure
API must return subRows array:
{
"id": 1,
"name": "Parent",
"subRows": [ // ✅ Required
{
"id": 2,
"name": "Child 1"
}
]
}Add Expand Icon
import { ExpandIcon } from "@/components/data-table/expand-icon";
{
accessorKey: "name",
cell: ({ row }) => (
<div className="flex items-center gap-2">
<ExpandIcon row={row} /> {/* ✅ Add this */}
<span>{row.getValue("name")}</span>
</div>
),
}TypeScript Errors
Issue: Type errors with DataTable props
Solution:
Ensure proper type parameters:
// ✅ Correct: Specify your data type
<DataTable<User, any>
getColumns={getColumns}
fetchDataFn={useUsersData}
idField="id"
/>
// ❌ Wrong: Missing type parameters
<DataTable
getColumns={getColumns}
fetchDataFn={useUsersData}
idField="id"
/>Column Resizing Not Persisting
Issue: Column widths reset on page reload
Solution:
Add columnResizingTableId:
config={{
columnResizingTableId: "users-table", // ✅ Required for persistence
}}Column sizes are saved to localStorage with this ID as the key.
Performance Issues
Issue: Table is slow with large datasets
Solutions:
Use Server-Side Processing
Ensure all operations happen on the server:
// ✅ Server handles pagination
fetchUsers({ page: 1, limit: 10 }) // Returns only 10 items
// ❌ Client-side pagination
const allUsers = fetchAllUsers() // Returns thousands of itemsReduce Page Size
pageSizeOptions={[10, 20, 50]} // ✅ Smaller max size
// vs
pageSizeOptions={[10, 50, 100, 500]} // ❌ Too largeLimit Subrows
// Return max 20 subrows per parent
subRows: items.slice(0, 20)Add Database Indexes
CREATE INDEX idx_users_name ON users(name);
CREATE INDEX idx_users_created_at ON users(created_at);URL State Not Working
Issue: URL doesn't update or state isn't restored
Solution:
Enable URL State
config={{
enableUrlState: true, // ✅ Must be enabled
}}Use Suspense Boundary
<Suspense fallback={<div>Loading...</div>}>
<DataTable {...props} />
</Suspense>Check for Client Component
"use client"; // ✅ Required at top of file
import { DataTable } from "@/components/data-table/data-table";Form Validation Errors Not Showing
Issue: FormMessage component doesn't display errors
Solution:
Ensure FormMessage is included:
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" {...field} />
</FormControl>
<FormMessage /> {/* ✅ Required */}
</FormItem>
)}
/>Getting Help
If your issue isn't covered here:
- Check Browser Console - Look for error messages
- Check Network Tab - Inspect API requests/responses
- Review Examples - Compare with working implementations
- GitHub Issues - Search or create an issue
- API Documentation - Verify your API matches the spec
Next Steps
- Best Practices - Optimize your implementation
- Server Implementation - Build the backend
- Examples - See working code
How is this guide?