Overview
Here we will see the entire process of building a data fetching function according to specific API capabilities.
The external API
For example, an API offering these parameters for querying data:
https://api.mysite.com/users?
limit=10 # rows per page
&offset=20 # offset (20 = page number 3)
&q=michel # full text search
&city=limoge # column filter: where "city" = 'limoge'
&sort=age
&order=desc # order by "age" descending
Bind your data fetching function to the TableHandler
Once you instantiated a new TableHandler
, you have to specify a data fetching function using the load
method. This function is a callback accessing a state
argument, which represents the client-side state of the datatable.
Your data fetching function will run every time a change occurs, such as when a user sorts or filters the data.
<script lang="ts">
import { type State, TableHandler } from '@vincjo/datatables/server'
import { myFunction } from './api'
const table = new TableHandler([], { rowsPerPage: 10 })
table.load((state: State) => myFunction(state): Promise<Row[]> )
</script>
State (= client-side table state)
The state argument reprensents a snapshot of the datatable:
type State = {
currentPage: number,
rowsPerPage: number,
offset: number,
search: string | undefined,
sort: { field: string, direction: 'asc' | 'desc' } | undefined,
filters: { field: string, value: unknown }[] | undefined,
setTotalRows: (value: number) => void
}
The wrapper function
Here is an example of translation from client-side state to a proper URL query string.
import type { State } from '@vincjo/datatables/server'
export const myFunction = async (state: State) => {
const response = await fetch(
`https://api.mysite.com/users?${getParams(state)}`
)
const json = await response.json()
state.setTotalRows(json.count)
return json.rows
}
const getParams = ({ offset, rowsPerPage, search, sort, filters }: State) => {
let params = `offset=${offset}&limit=${rowsPerPage}`
if (search) params += `&q=${search}`
if (sort) params += `&sort=${sort.field}&order=${sort.direction}`
if (filters) params += filters.map(({ field, value }) => `&${field}=${value}`).join()
return params
}
Trigger reload
”table.invalidate()
” runs your data fetching function and updates table rows.
table.invalidate()