Javascript push Object to global array overwrites previous values? - javascript

I'm having this problem in Javascript: I want to get the longitude and latitude values from an array of Objects. This all works fine, but when I try to save it into a global array, it overwrites every previous value. The result is an array with 8 times the last pushed object.
Global array: var _coordinates = [];
function getCoordinates()
{
mark = {};
for(var key in _data)
{
if(_data.hasOwnProperty(key)){
mark["lng"] = _data[key].long;
mark["lat"] = _data[key].lat;
}
console.log(mark); // Returns different coordinates (yay)
_coordinates.push(mark);
}
console.log(_coordinates); // All coordinates are the same (meh)
}
This is my first time asking a question here. So if I forgot something, please say so.

You could try to declare and instantiate the mark object inside the for loop because right now you are modifying the same instance all the time:
function getCoordinates() {
for(var key in _data) {
var mark = {};
if(_data.hasOwnProperty(key)) {
mark["lng"] = _data[key].long;
mark["lat"] = _data[key].lat;
}
_coordinates.push(mark);
}
console.log(_coordinates);
}

The problem is that you are repeatedly modifying the same object. Your array ends up containing eight references to that one object.
To fix, move
mark = {};
into the for loop.

You are mutating the (global) variable mark in every loop. Do this instead
_coordinates.push({lng: _data[key].long, lat: data[key].lat});

Related

Cannot update local variable

Have been trying to update a local variable (which is an array) via add/remove functions. I was able to add items using add function which also updated my local array but when I tried to remove the same using my code, it still returns my old array without modifications.
However, if I try to use pop() for removing an element, everything seems to work fine.
I know that filter from my remove function is returning the modified array but it's not getting updated in my array named mainArr.
Why is the array getting updated when I replace remove functionality with mainArr.pop() but not with my code.
The code also seems to work if I replace the assignment operator from my remove function to this.mainArr = //return value from the filter.
My remove function seems to be creating a new local variable with the same name mainArr due to which it is not updating my actual mainArr. Why is it doing so? Isn't it a concept of closures that my inner function can access global variables? What am I missing here?
function test() {
let mainArr = [];
function add(func) {
mainArr.push(func);
}
function remove(num) {
mainArr = mainArr.filter(item => item !== num)
}
return {
mainArr,
add,
remove
}
}
let val = test()
val.mainArr // returns []
val.add(3)
val.add(5)
val.mainArr //returns [3, 5]
val.remove(3)
console.log(val.mainArr) // still returns [3, 5]. Why?
mainArr.push(func); mutates the array.
mainArr.filter(item => item !== num) creates a new array.
let mainArr = []; is a variable which holds your original array. Later on, you assign the filtered version to the variable.
return { mainArr, add, remove } returns the value of mainArr which (at the time) is the original array. When you later change the value of the mainArr variable, the previously returned value is still the original array (no time travel is performed!).
Create the object upfront, and then always modify properties of that object. Don't create it from variables which later have their values changed.
function test() {
function add(func) {
data.mainArr.push(func);
}
function remove(num) {
data.mainArr = data.mainArr.filter(item => item !== num)
}
const data = {
mainArr: [],
add,
remove
};
return data;
}
let val = test()
console.log(val.mainArr);
val.add(3)
val.add(5)
console.log(val.mainArr)
val.remove(3)
console.log(val.mainArr)
In modern JS, this sort of thing is generally done with a class rather than a factory though.
class Test {
constructor() {
this.mainArr = [];
}
add(value) {
this.mainArr.push(value);
}
remove(value) {
this.mainArr = this.mainArr.filter(item => item !== value)
}
}
let val = new Test()
console.log(val.mainArr);
val.add(3)
val.add(5)
console.log(val.mainArr)
val.remove(3)
console.log(val.mainArr)

Variable assigned to array not updating when array does (JS)

I am assigning a variable, proxies, equal to an array. I am trying to add items to that array at a later point in time and then access that array in other files.
The problem is, the proxyHelper.proxies value is not updating to reflect the value of proxies variable.
After modifying the array, console.log(proxies) returns the modified array, but console.log(proxyHelper.proxies) returns a blank. I need to access the proxyHelper.proxies value in other files, so you can see why this is a problem.
I use similar code elsewhere and it works fine - what am I not seeing?
var proxies = [];
proxyHelper.proxies = proxies;
proxyHelper.tester = function(win) {
electron.ipcMain.on('saveProxies', function(event, data) {
// Clear the previous proxies from list
proxies = [];
// Split proxies based on line breaks
if (data != '') {
let proxiesList = data.split('\n');
// i<= because we want to run a check to see if all proxies are added
for (let i = 0; i <= proxiesList.length; i++) {
// if the for loop hasn't ran through all proxies
if (i + 1 <= proxiesList.length) {
proxies.push(proxiesList[i]);
}
// Once it's loop through all proxies
else {
//Returns nothing
console.log(proxyHelper.proxies);
//Returns array with added items
console.log(proxies);
win.webContents.send('goodProxies', 'Saved!');
}
}
} else {
win.webContents.send('emptyProxies', 'Empty.');
}
})
}
proxies = [];
You just assigned a new array to this variable.
proxyHelper.proxies still points to the previous value, and is not affected.
You should always use a single variable, or mutate it instead of re-assigning it.
Here is what is going on in your code:
var proxies = []; // This new variable ("proxies") contains a reference to an empty array.
proxyHelper.proxies = proxies; // You assign the same reference to a property
// (named "proxies") of the "proxyHelper"
// object. The "proxies" property points
// to the same empty array as the variable above.
proxyHelper.tester = function(win) {
electron.ipcMain.on('saveProxies', function(event, data) {
proxies = []; // You assign a new reference to the global variable
// "proxies", which points to a new empty array.
// At this point the reference assigned to
// "proxyHelper.proxies" is still the original
// empty array from line 1
// ...
}
// ...
}
So when you access "proxyHelper.proxies", you are always accessing the original empty array the has never been modified...
What you should do is:
proxyHelper.proxies = []; // resets the object's property to a new empty array
Don't need proxy variable, as its changes aren't reflected to proxyHelper.proxies
Just use proxyHelper.proxies itself
Also i've cleaned up your code a little bit
There are plenty of Array methods you can use, instead of for loop
proxyHelper.proxies = []
proxyHelper.tester = function(win) {
electron.ipcMain.on('saveProxies', function(event, data) {
//Split proxies based on line breaks
if (data != '') {
let proxiesList = data.split('\n');
proxiesList.forEach(function(proxy) {
proxyHelper.proxies.push(proxy)
})
win.webContents.send('goodProxies', 'Saved!');
} else {
win.webContents.send('emptyProxies', 'Empty.');
}
})
}

Javascript: Dictionary 'key' value becomes null outside for loop

I have a function which takes a list of dictionaries [{}] as an argument. It manipulates this list of dicts by adding a new key: value pair to it where value is again a list of dictionaries. This is what the function looks like, I've added comments to explain it.
function addFilesToProjects(nonUniqueArray, lists) {
var fileList = [{}]; //this will contain the list of dictionaries that I want to add as a key to the array 'nonUniqueArray'
var filesArray = []; //this was just for testing purposes because I want to access the modified version of nonUniqueArray outside the function, which I'm not able to (it shows undefined for the new key:value pair)
for (var i = 0; i < nonUniqueArray.length; i++) {
lists.forEach(function (list) {
fileNameString = JSON.stringify(list['name']).slice(2, -2);
if (fileNameString.indexOf(nonUniqueArray[i]['title']) !== -1 && fileNameString !== nonUniqueArray[i]['title']) {
fileList.push({
'name': fileNameString
});
}
});
nonUniqueArray[i]['files'] = fileList;
//this logs out the right key:value pair to the console
console.log(nonUniqueArray[i]);
filesArray.push(nonUniqueArray[i]);
while (fileList.length > 0) {
fileList.pop();
}
}
//however, now I get everything as before except the new 'files' key has empty list [] as its value :(
console.log(nonUniqueArray);
return filesArray;
}
I have no clue why is this happening, can someone help?
You seem to think that you are adding a copy of fileList into each dictionary, but in fact are adding the same fileList into each (that is, each is a reference to the same object) so that, as #vlaz points out, when you empty out the original, you are in fact emptying out what appears in each dictionary.

Unwrap objects in array

I have an array of objects:
var Props = [booleanPoint, buttonPoint, checkboxPoint, datePoint, dialPoint, gaugePoint,
groupboxPoint, htmlPoint, imagePoint, livetextPoint, livetrendsPoint, permissionsPoint,
rangePoint, selectPoint, spectrumPoint];
Console log shows:
Edited:
I want to extract the properties inside each object. How do I do it?
To be clear I just want the first property in the array, so that I can do Props.booleanPoint, Props.buttonPoint etc.
You question is not very clear, but I guess you're trying to extract the first (and only) property from each object in the list, whose name you don't know.
If yes, consider this:
extracted = Props.map(function(obj) {
for(var p in obj)
return obj[p];
});
If you want to combine all properties into one big object, try this:
allProps = Object.assign.apply(null, Props)
I'm not sure exactly what result you're after, but the best solution is probably either a forEach or a map.
var properties = {};
Props.forEach(function(object) {
// update properties somehow based on object
});
or
var properties = Props.map(function(object) {
return [some property of object];
});
The first just runs some code on each entry in the array; the second returns a new array with the results of that code.
Otherwise, the classic for loop works too:
var properties = {};
for (var i = 0; i < Props.length; i++ {
// update properties somehow based on Props[i]
}

Changing the value of one variable affects the value of variable which was previously assigned to it

I am getting values returned from mongodb in docs in the below code
collection.find({"Stories._id":ObjectID(storyId)}, {"Stories.$":1}, function (e, docs) {
var results = docs;
results[0].Stories = [];
}
I am assigning the value of docs to results. Then i change one array in that results to an empty array. The problem i face is, if I change the value of results, the value of docs is also getting affected!!
How can i change value of results[0] alone?
A simple JSFIDDLE link
This is because in java-script array and object are mutable by nature.
If y is an object, the following statement will not create a copy of y:
var x = y; // This will not create a copy of y.
The object x is not a copy of y. It is y. Both x and y points to the same object.
Any changes to y will also change x, because x and y are the same object.
You can use simply use of following solution:
In Jquery
results = $.extend(true,{},docs);//For deep copy
results = $.extend({},docs);//For shallow copy
results = JSON.parse(JSON.stringify(docs))
In Javascript
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
}
return target;
}
results = clone(docs);
You can change the value of 'results[0]' alone without effecting the 'docs' by using the scope concept. Try making the changes in a function rather than in an immediate line or at the same hierarchy.
I have written a sample here at Fiddle
A few months back, I was experimenting on how the concept of pass by reference works in terms of Objects in JS. We have to note that the return type of ds.find() is a json. You can read my article here
Thanks.
var docs = [1,2,3];
var results = docs;
console.log(results[0]);
var documents =[ {
'stories':'eshwar',
'place':'Hyd'
},
{
'stories':'Prasad',
'place':'Del'
},
{
'stories':'Hari',
'place':'Chennai'
}]
console.log(documents[2]); //prints {stories: "Hari", place: "Chennai"}
function ChangeAlone(documents){
var refDoc = documents;
refDoc[2] =[];
}
// the value of stories remains same in the parent object without change
console.log(documents[2].stories); //prints Hari

Categories

Resources