Alice Xu
Alice Xu

Reputation: 543

loop and push object into an array

HTML

<div class="row">
  <div class="col-xs-5 stateName">Kuala Lumpur</div>
  <div class="col-xs-7"><input id="1" placeholder="0.00" type="text"/></div>
</div>

<div class="row">
  <div class="col-xs-5 stateName">Kuala Kangsar</div>
  <div class="col-xs-7"><input id="2" placeholder="0.00" type="text"/></div>
</div>

MY JS

var stateArr = [],
    tempObj = {};

$('.stateName').each(function(){
  tempObj.id = $(this).next('div').find('input').attr('id');
  tempObj.name = $(this).text();                
  stateArr.push(tempObj);
});
console.log(stateArr)

My result were all Kuala Kangsar , any idea what's wrong in my loop? I thought I did the loop right as I push the object into the array in the loop?

Upvotes: 2

Views: 5120

Answers (3)

Pulkit Chaudhri
Pulkit Chaudhri

Reputation: 671

I've had a similar issue. This is because when you do following, you're only pushing a 'reference' to the object and when the object value is updated in the loop, the object that was pushed also changes value because it was merely a 'reference' and eventually the last value that was set in the loop is also set in the 'references', hence you see multiple values of the last object that was pushed.

stateArr.push(tempObj);

So, to tackle this issue you do the following:

stateArr.push(JSON.parse(JSON.stringify(tempObj))); //see Note below

The other way to prevent references is by doing the following:

let obj = { a: 1 };
let copy = Object.assign({}, obj); // Object.assign(target, ...sources)

obj.a = 2;
console.log(copy); // { a: 1 }
console.log(obj); // { a: 2 }

Note: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#warning_for_deep_clone

Upvotes: 0

Grundy
Grundy

Reputation: 13381

Yet another way with only jQuery

var arr = $('.stateName').map(function(index, el){
  return {
    id : $(this).next('div').find('input').attr('id'),
    name : $(this).text() 
  };
}).toArray();

console.log(arr);

document.getElementById('res').innerHTML = JSON.stringify(arr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
  <div class="col-xs-5 stateName">Kuala Lumpur</div>
  <div class="col-xs-7"><input id="1" placeholder="0.00" type="text"/></div>
</div>

<div class="row">
  <div class="col-xs-5 stateName">Kuala Kangsar</div>
  <div class="col-xs-7"><input id="2" placeholder="0.00" type="text"/></div>
</div>

<div id="res"></div>

Upvotes: 1

Balachandran
Balachandran

Reputation: 9637

Declare object inside loop tempObj={}

           var stateArr = [];
            $('.stateName').each(function(){
               var tempObj = {};  // declare obj inside loop
                tempObj['id'] = $(this).next('div').find('input').attr('id');
                tempObj['name'] = $(this).text();

                stateArr.push(tempObj);
            });

            console.log(stateArr);

Demo

Upvotes: 4

Related Questions