Inconsistent results looking up rows by unescaped and escaped rowId in DataTables 2.x but not 1.x
Inconsistent results looking up rows by unescaped and escaped rowId in DataTables 2.x but not 1.x

I'm using rowId to do lookups for rows. I've been escaping the id before doing the lookup and that's been working well in DataTables 1.x. Since migrating to DataTables 2.x I've been seeing inconsistent results doing those lookups and I'm pretty confused as to why. I've followed the instructions here regarding what characters are ok.
https://datatables.net/reference/option/rowId
Since upgrading to DataTables 2.x I'm now seeing a variety of different results when trying to do lookups. In some cases both the unescaped and escaped ids work. This is for an update to an existing record so the count should return 1.
This is another update but this time the unescaped id works but the escaped id doesn't (count returns 0). I can't tell why this would have problems the one above wouldn't (or vice versa).
In some cases the unescaped id throws an error (it's being interpreted as a css pseudo-selector) while the escaped version doesn't (it should return a count of 0 as in this case it's adding a new row). Not sure why there'd be a css pseudo-selector error here but not for the two cases above (or vice-versa).
I've also caught the code in the debugger and pulled the first row out of a table, grabbed the id and used it to look that same row back up both unescaped and escaped. In this case the unescaped version worked and the escaped version did not.
This is the escaping method I'm using:
static escapeMultiKeyForCssIdLookup (multiKey) {
return "#" + multiKey.replace(/[-[\]{}():*+?!.,%\\^$|#/\s]/g, '\\$&');
};
I didn't run into this issue with DataTables 1.x and I'm not sure what might be different in DataTables 2.x. This is the only ticket I could find that looked even vaguely related.
https://datatables.net/forums/discussion/comment/230364
I tried to reproduce this behavior in live.datatables.net but so far I've been unable to. I'm using the latest version of DataTables (2.3.2). I've also tried replacing the colons that are being used as delimiters in the ids with the | character but that didn't help. The result of all of this is some (but not all) rows that should be getting added, updated and deleted are failing to do so and the data in the table is now partially out of sync with the rest of the system. Any idea what might have changed or what I might be doing wrong?
Thanks.
Ben
Answers
For what it's worth, this is the furthest I've been able to get with an example so far. The first two ids work both unescaped and escaped. The third one throws an error unescaped but not escaped. If you add the missing id to the table then the unescaped error disappears.
https://live.datatables.net/suquqota/2/edit
If I comment out the third unescaped selector then the error isn't generated but the ID is not found:
https://live.datatables.net/suquqota/3/edit
However the third escaped ID looks like this:
But should look like this:
There was a space added at the incorrect spot. Now it works:
https://live.datatables.net/cagumici/1/edit
Your function seems to also work here:
https://live.datatables.net/cerinuga/1/edit
Kevin
It looks like Datatables creates a settings object called
aIds
, for example:Doing a cursory debug of datatables.js it looks like it will pass the
id
through to jQuery if its not found in the above object. Thus this error from jQuery:You can see the
aIds
object output in this test case:https://live.datatables.net/yefuyogi/1/edit
Note also the use of your function with the
generator:GEN-02:Is GEN-02 Test Mode Enterable
ID , the forth in your examples, which seems to work.I'm not sure where the problem might be.
Kevin
How are you updating the row data for the second screenshot?
Sorry keep thinking of ideas to try and look at
Kevin
Kevin,
Thanks for all the feedback.
To update a row I'm checking to make sure it's there first (though if I can't get the row to update I'm not sure it matters).
Still pretty confused as to why I can do what I showed in the last screenshot. That's just happening in the Chrome debugger. Pull a row out of a table, grab the id and then look it up without escaping it and it works and then look it up while escaping it and it fails. If anything I would expect that to be the other way around because it should be escaped. Very weird, assuming I'm not doing something stupid of course.
I've been working on a backup plan today. I've created an object to store a map of strings to uuids. This way I can stop using anything that needs escaping as a row id.
Then I can update the rowId definition to use it as well with a function (which incidentally is undocumented but mentioned in a comment on the rowId page - might be worth adding that to the official documentation):
It's far from ideal but it does seem to work and I'm not sure what else to do with the weird behavior I'm seeing trying to do lookups with escaped row ids.
Thanks.
Ben
Yep it's strange. I just tried the console statements of the last screenshot and it works with my last test case:
It sounds like the unescaped ID always works if the row exists but the exception is thrown when it doesn't exist. Is this correct? If so maybe use a try / catch statement with the unescaped ID. If there is an exception the catch block should execute. Like this:
Note the extra colon at the end of the ID string.
Kevin
Goodness me, you are good Kevin! That is exactly what is happening. This is the relevant code, and there is a specific comment I put in about it falling though to jQuery if the row id doesn't match the cached values.
I'm nervous about putting some code in to resolve this specific case - the row selector needs to be able to take a full CSS expression (i.e. spaces, colons, etc all have meaning). I'm not immediately sure how to resolve that dichotomy, other than to suggest simplifying your ids I'm afraid.
Allan
I should have saved my self some time and let you answer but some puzzles are just to fun
That is the code I found.
Kevin
Kevin and Allan,
Thanks for looking into this.
Kevin - what's with the extra colon that you added to the end of the id? I must have missed why you did that.
Allan - I actually stumbled onto that code when I was searching the codebase for the word "escape" hoping to find some clue as to what was going on but I didn't really know what I was looking at apparently.
Understandable about not wanting to add a bunch of weird special case code. And at the moment I agree that on my end simpler seems a lot safer. I just can't explain what's going on with the last of the screenshots I posted where I can pull out an id, do a lookup with it and it works unescaped but if I escape it I get no results. I have no idea how that's possible - the row is very clearly there. And I know it works fine when you guys try it which makes it even weirder. I'm going to keep down the path of my backup plan to map everything over to uuids for the moment I think because those I know work, no escaping necessary. It also feels cleaner centralizing all of that rather than having to add try/catch blocks everywhere I do row lookups.
Thanks.
Ben
It is simply there to show that when an unescaped ID is not found the
catch
block is executed. Probably not important since you are going with your backup plan.Kevin
The cached ID that DataTables looks up is not escaped, so anything that escapes it would cause it to not match there. Which would mean that it will fall through into the jQuery selector, and my guess is that something is going wrong there - perhaps it doesn't handle one of the escaped sequences in sizzle or something.
Allan