Adhyatmik
Adhyatmik

Reputation: 1118

How to create a data object from the list of displayed element in the html

My html is like below:

<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_1" />
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_2" />
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_3" />
  </div>
</div>

Using jquery, I want to create an object like following from the above HTML:

[
  {
    position :1,
    url: "https://link_to_Item_1"
  },
  {
    position :"2",
    url: "https://link_to_Item_1"
  },
  {
    position :"3",
    url: "https://link_to_Item_2"
  }
]

I tried something like below:

var myData = [];
var myDataElements = {};
$('.list-item').find('a').each(function(index, ele){
    myDataElements.position = index;
    myDataElements.url = $(this).attr('href');
myData.push(myDataElements);    
});

But the result was the position and URL became the same for all elements in myData.

Upvotes: 3

Views: 63

Answers (3)

Zakaria Acharki
Zakaria Acharki

Reputation: 67525

You need to initialize the variable myDataElements inside the loop :

var myDataElements = {};

And make sure you're closing the anchor tag well like :

<a href="https://link_to_Item_1"></a>

Instead of :

<a href="https://link_to_Item_1" />

NOTE: You can increase the index by 1 if you want to start counting from 1 instead of zero since the index is zero-based.

var myData = [];

$('.list-item a').each(function(index, ele) {
  var myDataElements = {};

  myDataElements.position = index + 1;
  myDataElements.url = $(this).attr('href');

  myData.push(myDataElements);
});

console.log(myData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_1"></a>
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_2"></a>
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_3"></a>
  </div>
</div>

Upvotes: 2

Arup Rakshit
Arup Rakshit

Reputation: 118289

myDataElements here pointing to the same object. And with each iteration you are basically changing the value of its 2 properties, position and url and then pushing it to the array. All array elements of myData are same object which you created here var myDataElements = {};. That's is why you ended up with same objects in myData.

What you want here is:

myData.push(Object.assign({}, myDataElements);
// or  myData.push({...myDataElements});

Now you are creating a new object by copying the myDataElements before pushing it it the array myData. This gives you the desired output.

Upvotes: 1

Mamun
Mamun

Reputation: 68923

The issue is you are declaring the object outside. But you need the object in each iteration, declare that inside the function:

var myData = [];
$('.list-item').find('a').each(function(index, ele){
  var myDataElements = {};
  myDataElements.position = index + 1;
  myDataElements.url = $(this).attr('href');
  myData.push(myDataElements);    
});
console.log(myData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_1" />
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_2" />
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_3" />
  </div>
</div>

You can also use jQuery's .map() and .get() like the following way:

var myData = $('.details').map(function(i, el){
  return {
    position: i+1,
    url: $(el).find('a').attr('href')
  }
}).get();
console.log(myData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_1" />
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_2" />
  </div>
</div>
<div class="list-item">
  <div class="details">
    <a href="https://link_to_Item_3" />
  </div>
</div>

Upvotes: 5

Related Questions