Do not mutate objects
See original GitHub issueI’m submitting a … (check one with “x”)
[x] bug report => search github for a similar issue or PR before submitting
[x] feature request
Current behavior
The table mutate the objects / raws with an $$index
property. code
Expected behavior Do not mutate objects.
What is the motivation / use case for changing the behavior? It is considered a bad practice to mutate objects sent by the user. With today’s modern language constructs it can be easily avoided.
The issues vary, here is a summery:
- Impossible to handle immutable objects
- Unintentional reflection of the
$$index
property - Usage conflict (the user or other 3rd party lib’s might be using
$$index
The user is not aware that this happens and this might create serious implications with the current implementation.
For example:
A user might use the ImmutableJS library or use Object.freeze/seal on the objects sent as rows, this will cause an exception by the library that can’t handle these objects. (ImmutableJS is a quite common library)
If an object is sent to the table and then used to create an HTTP request the $$index
property will be sent along with the request. This is unintentional reflection.
There are several solution to solve this, this is my preferred solution:
- Use
WeakMap
to store the index of every row, rows are automatically removed from theWeakMap
instance when removed from the table (and no longer referenced by the user). Each table instance should have aWeakMap
instance. It is possible to remove the row from the weekmap when removed from the table.
// somewhere at construction:
this.idxMap = new WeakMap()
// set index:
this.idxMap.set(row, rowIndex);
// use this.idxMap.get to fetch the index.
This solution can’t create conflicts, it will not reflect on object serialization and it will not mutate the object.
Other possible solutions:
- Use a
Symbol
instead of a property, symbol are guaranteed not to conflict with any other library.
// somewhere at module's top:
IndexSymbol = Symbol('ngx-datatable RowIndex');
// set:
row[IndexSymbol] = rowIndex;
// get
row[IndexSymbol]
This solve any conflict and will not reflect in serialization but it will throw on immutable objects.
- Assign
$$index
with a property descriptor so the value is not enumerable.
Object.defineProperty(row, '$$index', { value: rowIndex });
This does not solve usage conflicts and mutates the object, not good.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:12 (6 by maintainers)
Top GitHub Comments
Planning on this for next release, probably be in July sometime.
done in 10.0.0!!!