2

I have this line in my code:

$(".view" + nodeID).data("urls",viewURLs);

(nodeID is a variable I increment for each element) After that, another element with the same class is added to the DOM. And later on, I have:

alert($(".view" + nodeID).data("urls"));

Which for some reason, displays "undefined". Now my question is: Could it be related to the fact that I added another element with the same class? Does it override the data? I'd expect jQuery to retain data for a class selector, even if its satisfying elements changed. Or am I missing something in the way selectors work? Thanks.

More details: When I set the data, nodeID contains a number which increases each time. Later, on a click event, the ID is extracted from a string that contains it and used in the expression to get the data:

var nodeElement=$(this).closest("table");
if (nodeElement==null) return;
var nodeFullID=nodeElement.attr("id");
var separatorIndex=nodeFullID.indexOf("-");
if (separatorIndex==-1) return;
var nodeID=nodeFullID.substring(4,separatorIndex);
alert($(".view" + nodeID).data("urls"));

Could it be related to the fact that to set the data, nodeID is treated as a number, and then joined to a string to compose the selector, and to get the data, nodeID is extracted from a string?

user940016
  • 2,878
  • 7
  • 35
  • 56

1 Answers1

1

Your assumption

I'd expect jQuery to retain data for a class selector

is unfortunately wrong. The data is stored on an element-base and not on a selector-base. So:

$(".view" + nodeID).data("urls",viewURLs);

Will set that data on all elements within the result-set of $(".view" + nodeID). When adding new elements to the DOM, those elements wont (magically) have that data stored.

When executing

$(".view" + nodeID).data("urls")

jQuery will return the data of the first element in the result-set. If that happens to be your newly added element, the result will be undefined. As per manual:

Return the value at the named data store for the first element in the jQuery collection

Well, that's what is going wrong. Possible solutions are

A) Have a variable within your code that stores the urls per nodeID:

// Define it somewhere
var urlsPerNode = {};
// Add it somewhere
urlsPerNode[ nodeID ] = urls;
// And debug it
alert(urlsPerNode[ nodeID ]);

Remember that the variable should be in scope everywhere you want to access it.

B) Store the data("urls", viewURLs) everytime you add a new element to the DOM. Storing it only to that new element is sufficient enough

var newElement = ...; // your logic
$(newElement).data("urls", viewURLs); 

By the way, if your .view + nodeID is the table in your given code, you can simply read it out by:

alert( $(this).closest("table").data("urls") );

as jQuery stores the data on the element, and not on the used selector.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Peter van der Wal
  • 11,141
  • 2
  • 21
  • 29