Using mui-datatables in a type-safe way by having access to the original object
See original GitHub issue(largely based on my similar reply to issue #109, but decided it was more appropriate to start an issue as well to get the discussion rolling)
Hi @gregnb, thank you for your great work on this.
I wonder if it’s possible use mui-datatables
in a more “type-safe” way. Maybe it’s already available or maybe it’s something that can be easily implemented.
Currently we specify the columns as such:
const columns = [
{
name: 'object_field',
label: 'Object field label'
}
}
This will take the object_field
field from each object in the array sent to data
. However, specifying the field name as a string isn’t type-safe. TypeScript has no way of knowing whether objects in data
contain or don’t contain the field object_field
.
Question:
Is it possible perhaps, instead of having name
as a required field, another option could be added? (let’s call it value
, required when name
isn’t specified), that would be used as such:
const columns = [
{
value: (obj) => obj.object_field,
label: 'Object field'
}
}
This way, we could use it with TypeScript:
value: (obj: KnownType) => obj.object_field,
…and TypeScript would check that object_field
does indeed belong to KnownType
. Since it’s an extra option, it wouldn’t interfere with the current way of doing things or JS-only users.
Would also be nice to get the original data object in customBodyRender
. Use case for this is: if we want to render one column based on a value from another.
Right now we do have access to the values array in tableMeta.rowData
, The caveat is: the order matters. Changing the column order requires a change in how we access tableMeta.rowData
. But would be nice to be able to keep the type information if using TypeScript.
So maybe we could have the original object available in the parameters sent to customBodyRender
?
What are your thoughts? Thanks!
Issue Analytics
- State:
- Created 5 years ago
- Reactions:5
- Comments:7 (3 by maintainers)
I second better typescript support and flexible value resolution, but putting those points aside, the lacking source object parameter in
customBodyRender
method is an appreciable drawback. I wanted to render two fields of an object into one column but I was forced to add the other field to schema as an excluded field. (Which also changed row index, since it matters).@gregnb thanks for your prompt reply. In the meanwhile, I’ve written an API that sits in front of the
mui-datatables
API and does exactly what I wanted 😃.It takes:
label
, and two functions: one for formatting thevalue
(used for sorting and searching), the other used torender
what gets displayed).It then produces
mui-datatables
-compatibledata
andcolumns
that can be plugged directly into<MUIDataTable />
.What happens under the hood is that I use a hidden (
{display: "excluded"}
) column to hold the raw object data, which I then get to fully access in thecustomBodyRender
of every cell from theMUIDataTableMeta
’srowData
, when rendering.The
data
sent to<MUIDataTable />
will be an array of objects with the following structure:As mentioned previously, the
data1
…dataN
fields will be the values used for sorting and searching, while the original raw object will be used when displaying the data.Long story short, here’s how I use it:
Note 1: The functions passed to
value
andrender
will know thatMyObjectType
contains fieldsfield1
,field2
. ParameteroriginalData
is of typeMyObjectType[]
Note 2: Real-life use cases are much more complex than just rendering the raw value. I’m drawing graphs, rendering the same data differently based on the column it’s in, using values from multiple fields to render a single cell, etc. This logic can all be painlessly specified in the
definitions
object above.This is the code that’s working behind the scenes, if anyone’s interested: