Doom Doom - 3 months ago 9
Ajax Question

JS not set varible after loop

I can`t get why in my function not changing value of variable. Here my code.

var count = function(datain){
let temparr = [],
countobj = {};

$.each(datain, function(key, val) {
console.log(temparr);
countobj.cost = +$(val).find("[name]").text();
console.log(countobj);
temparr.push(countobj);
console.log(temparr);
});

console.log(temparr);
return temparr;
};

let countarr = count(datain);
console.log(countarr);


This function part of function that fires on ajax success, ajax i call on some select changes. Datain - result of ajax. At first time call this function work`s fine, but all another fires returns me first time set countarr. All data in key, val - correct, but i cant understand why "countarr" returns me result of first call and not re-set temparr inside function.
Thanks for reply!

Answer

You're reusing the same countobj object on each loop, pushing a reference to that single object repeatedly into the array.

You need to create a new object on each loop:

var count = function(datain) {
    let temparr = [],
        countobj;                                          // ***
    $.each(datain, function(key, val) {
        countobj = {};                                     // ***
        console.log(temparr);
        countobj.cost = +$(val).find("[name]").text();
        console.log(countobj);
        temparr.push(countobj);
        console.log(temparr);
    });
    console.log(temparr);
    return temparr;
};
let countarr = count(datain);
console.log(countarr);

As there's just the one property, you don't need a variable. Here's that same code without the variable and with the console.log lines removed:

var count = function(datain) {
    let temparr = [];
    $.each(datain, function(key, val) {
        temparr.push({cost: +$(val).find("[name]").text()});
    });
    return temparr;
};
let countarr = count(datain);
console.log(countarr);

Or you could even use map; and since you're using ES2015+ (I can tell from let), we can use an arrow function:

let count = function(datain) {
    return datain.map(val => ({cost: +$(val).find("[name]").text()}));
};
let countarr = count(datain);
console.log(countarr);

If datain is only array-like, not an actual array, use Array.from instead of map:

let count = function(datain) {
    return Array.from(datain, val => ({cost: +$(val).find("[name]").text()}));
};
let countarr = count(datain);
console.log(countarr);