0

I have a list of html elements with data attributes, which I would like to assemble into a jQuery object and manipulate the values.

What is the best way to dynamically add these in an each loop so that I can easily access the data as so: data.name and data.name.prop?

I want all the naming conventions to be dynamic and based on the data.

I based my code on the top answer from here: How to create dynamically named JavaScript object properties?

So far I have:

$('.licences-list .data div').each(function(index) { 
    var data = {}
    cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
    cats.push(data)
})

But when I try to iterate over the data array, like so:

$.each(cats, function(key, value){
    $('<div class="card"><p>'+value+'</p></div>').appendTo('#commercial-licenses');
});

I just get [object Object] output... and I'm not sure why!

byzantine cucumber
  • 531
  • 1
  • 5
  • 12

2 Answers2

2
var data = {}
    cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')

Each time you loop through, you're actually just adding an empty object (data) to your array (cats). You're then assigning a named property to that array (cats) which $.each has no idea about (it ignores them because it's iterating over an actual array).

My guess is you want an object map which is something like: var cats = { "f1": "feline 1", "f2": "feline " };

In that case what you want is:

var cats = {};
$('.licences-list .data div').each(function(index) { 
    cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
})

If you want an array that contain more values than just strings (or whatever data you have added to the element), you create new objects each time and append them to the cats array:

var cats = [];
$('.licences-list .data div').each(function(index) { 
    cats.push({
       'id': $(this).find('p').data('cat'),
       'name':  $(this).find('p').data('catname')
    });
})

This will then give you an array that you can use $.each over, and access the values using: value.id, value.name

Mark R
  • 136
  • 2
  • 6
  • Many thanks for this. I think you're right about the map being the way to go. The only problem is I would like the keys to be named dynamically, based upon the name of the data-attribute of the div in the example. Something like `data-cat="category1"` and `data-catname="Category 1"` which I can then use as `cats.cat` and `cats.catname` -- or thereabouts. – byzantine cucumber Aug 23 '19 at 06:54
  • 2
    In your code, cats is an array, so I assume you actually mean the individual cats contained within it. That being the case, see here https://stackoverflow.com/questions/14645806/get-all-attributes-of-an-element-using-jquery for how to get all of the attributes. Alternatively you could just use one attribute and encode the data inside it in JSON. This has the benefit of typing and hierarchical information. – Mark R Aug 23 '19 at 14:25
1

Don't over complicate it.

$('.div').attr('data-attribute', 'data-value');

using your example:

$('.licences-list .data div').attr('attribute-name', 'attribute-value');
Jay Jordan
  • 643
  • 4
  • 16
  • You have got me thinking actually, I could manipulate the elements instead of manipulating the data. I still really want to know the correct way to do this kind of thing using jQuery objects -- I'm often hitting the same problem. Thanks for your input though! – byzantine cucumber Aug 23 '19 at 06:47