Alko
Alko

Reputation: 1439

jQuery each and map to a new object based on data-attribute

I'm trying to extract all IDs from multiple elements based on data-attribute.

Here is my html:

<div class="row">
  <div class="item" data-element='{"id":1, "name":"John"}'>John</div>
  <div class="item"></div>
</div>
<div class="row">
  <div class="item"data-element='{"id":2, "name":"Peter"}'>Peter</div>
  <div class="item"></div>
</div>

and javascript:

var result = [];
$('[data-element]').each(function() {
    result = $(this).data('element');
}); 

$.map(result, function( val, i ) {
   console.log(val)
});

The problem is that I only get the last element. Console log shows 2 Peter.

What I would like to be the final result is all id's as well as names extracted in form of an array like:

id = [1,2]
name = ['John', 'Peter']

Upvotes: 2

Views: 2969

Answers (3)

cstad
cstad

Reputation: 1

You are setting an empty array to the value of $(this).data('element') on every iteration of your forEach loop. So, the last iteration will always be the value of result when you evaluate it. Use the Array methods to add items to the array instead of setting it; so instead of result = $(this).data('element'); it should be result.push($(this).data('element'));

Upvotes: 0

charlietfl
charlietfl

Reputation: 171669

Start with empty arrays and push each value into corresponding array within one loop. You seem to be over complicating it

var arrObj={ id:[], name:[] };

$('[data-element]').each(function() {
   var data = $(this).data('element');
   arrObj.id.push(data.id);
   arrObj.name.push(data.name);
});

console.log(JSON.stringify(arrObj,null,' '))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="row">
  <div class="item" data-element='{"id":1, "name":"John"}'>John</div>
  <div class="item"></div>
</div>
<div class="row">
  <div class="item"data-element='{"id":2, "name":"Peter"}'>Peter</div>
  <div class="item"></div>
</div>

If you had a lot of properties and wanted each property value in an array you could run another internal loop over the properties instead of manually writing each push, something like:

$.each(data, function(key, value){
   arrObj[key].push(value);
})

Upvotes: 2

Dekel
Dekel

Reputation: 62556

You should use the map inside the each function you have:

var result = [];
var id = [];
var name = [];
$('[data-element]').each(function() {
  result = $(this).data('element');
  
  id[id.length] = result.id;
  name[name.length] = result.name;
  
  $.map(result, function( val, i ) {
    console.log(val)
  });
  
});

console.log(id)
console.log(name)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
  <div class="item" data-element='{"id":1, "name":"John"}'>John</div>
  <div class="item"></div>
</div>
<div class="row">
  <div class="item"data-element='{"id":2, "name":"Peter"}'>Peter</div>
  <div class="item"></div>
</div>

Otherwise - the each function walk over all your elements, and when the loop is done - the value in result is the value of the last element that has [data-element] attribute (and you map the function to that result).

Based on what you want to get - I'm not sure you even need the map function there. Check the usage of result.id and result.name in my code.

Upvotes: 0

Related Questions