Row gets duplicated when I update rows with same id
Row gets duplicated when I update rows with same id
Hello,
I have a problem adding/updating data to DataTables. I am using JSON data, but do not use the ajax API, but rather I get the json data by jquery and pass it to DataTable. After Initial table setup, that works well, I try to add some rows via these calls:
function updateData(data){
$.each(data.table.data, function(i, v){
index = table.column(1).data().indexOf(v.id);
if(index < 0 ){
table.row.add(v); // row does not exist yet, so new one will be added
index = table.column(1).data().indexOf(v.id);
row = table.row(index);
} else {
row = table.row(index);
row.data(v);
}
});
// force new record to show up on top
table.order([defaultSortColumn, 'asc']).draw();
table.order([defaultSortColumn, 'desc']).draw();
}
table.data is an array of items of the same structure of the original init table data.
What I get is that the call:
index = table.column(1).data().indexOf(v.id);
does not find the newly added rows, so the code above is ending up to add duplicate rows when a newly added row gets an update having same id.
My question is: do I need to perform some call in order to update the DataTables internal data cache? Is that one the reason that prevents IndexOf to find the newly added row ids?
Thank you in advance for the help you may give.
Replies
Anyone?
I've just put together a little example to test this and it appears to work as expected: http://live.datatables.net/midumuxo/1/edit .
Can you link to a test case that shows the problem so I can debug it please.
Allan
Hello Mr. Jardine,
thanks for the quick reply. During debug I found that the issue is not with indexOf, but rather with something related to DOM duplication. Will get together a simplified test case and send you the link ASAP.
Hello Mr. Jardine,
after two months I got the time to get back to this, sorry for delay.
Basically I have an update function that polls the server for new rows and updates the DataTable in this way (debug code included):
the bug I am fighting with is that when a new value of the index in column 1 is sent from server, the row is created as expected, but as soon as an update for the same row (same value of column 1) is sent from server, a second row is created in DOM, despite the fact that the existant index is correctly found (see debug lines below). Furthermore, oddly, while the new row holds the new values and the old one retains the old ones, children rows are updated on both old and new row, as you can see in example below:
the function that updates child rows is the displayEvents listed below:
I tried several times to find the underlying bug without success, any clue?
Could you clarify the child row aspect - is the problem with the child row?
Can you give me a link to the page so I can debug it directly please?
Allan
Hi, I apologize for not being able to give you direct access to the page, it is a sensitive system and I have no permissions to do that. Nonetheless I did some further tests excluding the calls to the part of code that updates the child rows, the duplicate row problem persists, so it has nothing to do with child rows.
So the code which is causing the duplication is basically this one:
The initialization code of DataTable here is the following:
Here below you can find the payload of get responses being parsed by the updateData function.
the v.id in this case is the "aa8b6ae4-1e00-4fa7-bfd8-2426a345380d" value
first one - new row created correctly:
second one - duplication occurs:
third one - the duplicated row gets updated, the first one remains unchanged:
hope this can help/is sufficient to find the problem.
Hi,
seems that the origin of the problem is that the .row(index) method used above is not returning the expected row. I changed the function updateData as listed below, and the duplicated row bug cleared.
if you know a more elegant solution, please advise. I think this way to search and select for values is a little bit too convoluted.
Hi,
Thanks for posting back your findings. The code above is treating the
each
index from looping overdata.table.data
as the row index. I don't see wheredata.table.data
is defined, but my assumption from your findings is that it is not based on the row index (i.e.rows().data()
).You could use
rows().every()
to loop over the rows in the table, oriterator()
.Or if the above works for you, use that :-)
Allan
Hi,
the data.table.data is the data sent from ajax callback, of which you can see an example above, see just the part:
then the correspondant row id is searched by the line:
that should give back the right underlying table array row index (and seems that actually it does that). It seems that the problem is with the
row()DT
method called with the "row index selector"row-selectorDT
, passing to it theintegerJS
array index obtained from the call listed above, that gives back a row in DOM different from the one containing the v.id value in 2nd (index 1) column. By now I managed to solve my problem, but perhaps it would be worth to check this api to see if it is working as expected.The index selector doesn't have anything to do with the data in the row. It is an internal index maintained by DataTables -
row().index()
will give the index for a row.Allan
I already perfectly understood it. Perhaps you had just a quick glance on my posts and missed the point. What I am reporting is that in my former code I was first getting the "internal index" by using the call:
then I was trying to use such index to select a DOM row by calling the:
as documented in your APIs. But this call actually does not select the intended row, differently from what documentation says. So I thought that would have been useful to report this problem even if I managed to find a workaround for it. Hope this will help to improve this nice library.
But that doesn't return the internal index. It returns the current order index.
column()
when not given aselector-modifier
object uses the default options for the selector modifier, which is to return in the current display order.To get the data in index order use the
order
option of the selector modifier:Allan
Thank you for the tip, it wasn't immediate from documentation. I would suggest an addition to apis to get a fast selection of a row based on content. Also an API providing an out of the box way to reference columns by column name/title besides the already existant one that uses indexes would be handy. For example two apis with imaginary names of query and vert that would enable us to write something like:
would be very handy. Hope this could be interesting for you. Thank you very much for your attention!
You can use the selectors as functions which allows you to select by data. See the
row-selector
documentation, specifically the function option.However, yes, it would be nice if this would be easier to use and is somethingI plan to introduce in future.
Allan