JcDenton86 JcDenton86 - 3 months ago 12
Javascript Question

Javascript array.find() callback pushes same object to global array

I have this block of code:

wordObj.baseLang.find(function (item) {
if (item.hasOwnProperty("Example")) {
var exTranslation = wordObj.targetLang.filter(function (targetLangItem) {
if (targetLangItem.id === item.id) return targetLangItem.Example || '';
});
var obj=[item.id,wordObj.ID,lid,item.Example,(exTranslation[0] ? exTranslation[0].Example : null)];
console.log(obj);
insertquery2[1]=obj;
batchQueries.push(insertquery2);
}
});


where:
wordObj
is an object that contains a field
baseLang
which is an array of objects (and some of the objects in this array have the key
Example
). I also have a global array
batchQueries
which will hold subarrays like the one i am trying to create in the above code block. Array
insertquery2
has length 2:


  • insertquery2[0]
    has a string such as :
    "insert into tablename (col1,col2,col3,col4,col5) values (?,?,?,?,?)"
    and

  • insertquery2[1]
    will hold the actual values of the query (this is what the above code tries to do).



My goal is to create arrays of insert queries for the same table. i.e:

batchQueries = [
["insert into tablename (col1,col2,col3,col4,col5) values (?,?,?,?,?)",[val1,val2,val3,val4,val5]],
["insert into tablename (col1,col2,col3,col4,col5) values (?,?,?,?,?)",[val1,val2,val3,val4,val5]],
]


(I am limited to this structure of array).

My issue is that if I console.log
obj
, I can get the different values for each item, while adding the object in
insertquery2[1]
and then pushing it to the global array will show only the last item found.

I know that it has to do with pushing by value and callbacks but no matter what I've tried, I can't make it work yet

How can i fill the global array with all the different items that have the property
Example
?

thanks in advance. If you need any further info just ask!

Answer

Javascript always passes by value. However, if you pass an object to a function, the "value" is really a reference to that object, so the function can modify that object's properties but not cause the variable outside the function to point to some other object.

The reason you only see the last item found is because you're overwriting the second index in insertQuery2 (which is an object) in each iteration and passing it to the push function. Thus, insertquery2[1]=obj; is modifying the value each time and the last time it's modified is during the last iteration.

Instead of modifying insertQuery2, just make a new array:

var copyInsertQuery2 = [insertQuery2[0], obj];

and push that to batchQueries instead.