amexio.github.io icon indicating copy to clipboard operation
amexio.github.io copied to clipboard

DataTableComponent does not preserve object methods when using dataTableBindData

Open Chris-Slade opened this issue 7 years ago • 1 comments

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[x] Feature request
[ ] Documentation issue or request
[ ] Support request

Current behavior

The DataTableComponent does not preserve methods on the objects provided. This behavior works fine when using the http API for retrieving data for the table (since that data will be plain JSON), but the dataTableBindData API allows JavaScript/TypeScript objects that are more complex than what JSON can represent. For example, this means that I cannot use getter methods as dataIndexes. This is because the DataTableComponent code uses JSON.parse(JSON.stringify()) to clone the table's data, which does not copy methods.

Expected behavior

If I set dataReader to "data" and dataTableBindData to some object of type { "data": T[] }, I should be able to use methods belonging to objects of type T in the dataIndex of the table's columns.

Minimal reproduction of the problem with instructions

See this Plunker example. In this example I define a MyData object with a valueTimesTen getter. For example, new MyData(5).valueTimesTen === 50 is true. It also has a valueTimesTenMethod which behaves the same way, but is accessed as a function (i.e. .valueTimesTenMethod()). I initialized the data used in the table in the App constructor as an object with a dataReader "data" pointing to an array of MyData objects.

The table will correctly show one column for the value of each MyData, plus a column showing the value returned by the valueTimesTen getter and a template showing the value returned by the valueTimesTendMethod method.

The table displays as expected to begin with, but attempting to filter the table causes it to stop working. This is due to the data being copied without preserving the methods.

What is the motivation / use case for changing the behavior?

In my real-world application, I fetch the JSON data from a server and create objects from this data before adding it to my table with the dataTableBindData input. This allows me to make columns using templates that refer to "virtual" properties of the objects, which are defined as getter methods, without having to modify the JSON data returned by the server (which I need to keep an original copy of for other purposes).

Suggested Fix

If the objects in the data array are not modified by the DataTableComponent, the uses of JSON.parse(JSON.stringify(this.data)) can be replaced by this.data.splice(). (However, modifications of the objects by users of the library would affect the data in the table.) If they are modified, then a deep clone which preserves methods could be done with this.data.map(e => Object.assign({}, e)).

Environment

Angular version: 5.0.0.

Browser (tested in):

  • [x] Chrome (desktop) version 60.0.3112.78 For Tooling issues:

  • [x] Firefox version 57.0.3

  • Node version: v8.0.0

  • Platform: Windows

Chris-Slade avatar Jan 05 '18 16:01 Chris-Slade

We are working on this feature set for all the complex UI Components like Grid, Tree and Simpler components like Dropdowns, List Box etc. We really appreciate your feedback and looking forward to more such suggestions. Once the feature is ready, we will inform you personally.

Apologize for the delay in responding to this critical feature requirement.

arafkarsh avatar Jul 18 '18 11:07 arafkarsh