-1

If I know that a certain data property exists on an element and it is an object, how can I store something as a new property of that data object?

For example, I have this div:

<div id="theDiv" data-test1="{string: 'test 1 data'}"></div>

And I'm trying to set data on it like this:

div.data(["test1"]["number"], 1);

But that is getting me nowhere. And div.data(["test1"]["number"]) = 1; gets me a left-hand side in assignment error.

http://jsfiddle.net/VM8VW/

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
1252748
  • 14,597
  • 32
  • 109
  • 229
  • 1
    `["test1"]["number"]` makes no sense in javascript. I don't even know where you were going with that. – Kevin B Jul 17 '13 at 21:27
  • `["test1"]["number"]` evaluates to `undefined` because that expression tries to access an index (`"number"`) of a 1-element array (`["test1"]`). Could you clarify what you're trying to achieve? – Matt Ball Jul 17 '13 at 21:28
  • Is this what you were looking for? http://jsfiddle.net/VM8VW/1/ your json was invalid, and I assumed what you meant in my first comment – Kevin B Jul 17 '13 at 21:29

1 Answers1

5

You have to fetch the value and then re-save it:

div.data('test1', function(prev) {
  prev.number = 1;
  return prev;
}(div.data('test1')));

It's probably safe to just do this:

div.data('test1').number = 1;

but that sort of thing gives me the willies.

edit — if you want jQuery to understand your JSON as such, it has to be valid:

<div id="theDiv" data-test1='{"string": "test 1 data"}'></div>

Double quotes only, and property names must also be quoted.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • It's not your fault, but neither of these work, because `div.data("test1")` is a string (because it wasn't properly set in the attribute). If it were valid, this would definitely work :) And I don't see what the problem with the second example is, since it returns a reference – Ian Jul 17 '13 at 21:30
  • you don't have to re-save it either since it's an object reference, you can just edit them directly -- assuming you fix the invalid json string. Ah, i see you included that in your answer too. – Kevin B Jul 17 '13 at 21:31
  • @Ian oh I didn't check the fiddle; I took the OP for its word when it stipulated the value is an object :) – Pointy Jul 17 '13 at 21:31
  • @Pointy Yeah, my comment probably made more sense for the OP, not on your answer :) – Ian Jul 17 '13 at 21:32
  • @KevinB yes that's the part that makes me nervous. It probably shouldn't, but assuming I can poke around like that causes part of my reptile brain to twitch. – Pointy Jul 17 '13 at 21:32
  • Yeah, it isn't safe if a string is stored in the data entry, but if it's an object, it is safe. The fact that it can be either or is probably enough to say, do it the way it'l work all the time rather than just sometimes. – Kevin B Jul 17 '13 at 21:33
  • okay. this is interesting. One last question. I notice that `div.data("object").inner = div.data("object").inner || 2;` works as expected. But simply checking for the existence of object and then creating it if it isn't there ( `div.data("object") = div.data("object") || {};` ) gives me an error: Invalid left-hand side in assignment. Why is this? – 1252748 Jul 17 '13 at 21:40
  • @thomas `div.data("key")` returns an object. You can't set the value of an existing object. To set **data**, you use `div.data("key", "value")` – Ian Jul 17 '13 at 21:41
  • @Ian so by writing `div.data("key")` I immediately create it, thereby making it impossible to test for its existence. I'm a little confused by what you mean.. Thank you for your help. – 1252748 Jul 17 '13 at 22:36
  • 1
    @thomas no, that's not correct. If there's no "key" data element, then the result of that function call is `undefined`. The `.data()` function behaves differently depending on how many arguments are passed. When it's just one, it fetches any existing value, or else returns `undefined`. – Pointy Jul 17 '13 at 23:34