WHICH VERSION OF REACT ARE YOU USING?
Officially Supported:
[ ] v0.14.x
Community Supported:
[x] v15.0.x
WHICH BROWSER ARE YOU USING?
Officially Supported:
[ ] IE 9 / IE 10 / IE 11
[ ] Edge
[x] Chrome
Should work:
[ ] Firefox
[ ] Safari
I'm submitting a ... (check one with "x")
[ ] bug report
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/adazzle/react-data-grid/blob/master/CONTRIBUTING.md
Current behavior
Trying to display data for a nested object doesn't work without a custom formatter
{
name: 'Customer',
key: 'customer.name'
}
Expected/desired behavior
I would like to be able to access nested object properties using the above syntax or possibly with a function like below. Is this already possible somehow?
{
name: 'Customer',
key: 'customer',
accessor: (row) => row.name
}
What is the motivation / use case for changing the behavior?
Limits the number of custom formatters needed
馃憤
Please implement this!
I found a work around if you are interested.
In Row.js, they are calling row.get(key) as follow
getCellValue(key) {
let val;
if (key === 'select-row') {
return this.props.isSelected;
} else if (typeof this.props.row.get === 'function') {
val = this.props.row.get(key);
} else {
val = this.props.row[key];
}
return val;
}
I changed my rowGetter to implement get. I used eval to allow key of th type: array[0].key.name
rowGetter(index) {
let contract = this.props.contracts[index];
contract.get = key => eval('contract.' + key)
return contract;
}
Out of interest, how would this be achieved when using custom formatters? Wouldn't the fact that multiple columns can't have the same key prevent this? Each key would be the name of the same parent object, right?
@philipbulley Key does not necessarily have to be first level key of the object. Dot notated full path could be used as key to differentiate two columns. So in above example the key would be 'customer.name'.
@moizhb but the formatter is passed an empty string value when I use this example:
{
name: 'Customer',
key: 'customer.name'
}
馃挕 However, I've just found out that I can do:
{
name: 'Customer',
key: 'customer.name',
getRowMetaData: row => row.customer.name,
}
...then consume the customer name as a prop named dependentValue in the custom formatter. Which is a little odd, but it works 馃憤
@jean343 , you just fucking saved me hours, I also have updated my rowGetter function and it works very well, and I also got a generic way, where the keys don't need to have the same parent object, as mentioned by @philipbulley .
{
name: 'Customer',
key: 'customer.name'
}
I'm just checking if the key has a dot.
rowGetter = (rowIdx) => {
let rows = this.getRows();
let project = Object.assign({}, rows[rowIdx]);
project.get = key => {
let splitedkey = key.split(".");
if(key.includes('.')) {
return project[splitedkey[0]] ? project[splitedkey[0]][splitedkey[1]] : ""
} else {
return project[key]
}
};
return project;
};
Note: I'm always using the get function
I am glad it helped!
About the 'dot', I like that your solution does not use eval however it is limited at a specific pattern.
I would suggest something found from https://stackoverflow.com/questions/6393943/convert-javascript-string-in-dot-notation-into-an-object-reference
'a.b.etc'.split('.').reduce((o,i)=>o[i], obj)
I'm really thankful for your tip, I have changed my function to use the reduce function as you mentioned to get any pattern, so now I got a clean and generic code.
Continuing the discussion about nested object properties, has anyone tried to sort columns using this kind of data? After solve how to show the data, would be nice to have an option to sort my columns.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please reopen this if you feel it has been incorrectly closed and we will do our best to look into it. Thank you for your contributions.
An update on this issue, below is the code I used (modified from above) to allow multiple level of nesting if needed (it works it out)
feel free to optimise and post back - this is just the first pass at it
document.get = (key) => {
let splittedKey = key.split(".");
if(document && key.includes('.')) {
let current = document;
splittedKey.forEach((splitKey) => {
if(current) {
current = current[splitKey];
}
});
return current;
} else {
return document[key]
}
};
Most helpful comment
I found a work around if you are interested.
In Row.js, they are calling row.get(key) as follow
I changed my
rowGetterto implement get. I used eval to allow key of th type:array[0].key.name