Converting JSON not returning Javascript array - javascript

I have some JSON returning from my server that looks like this
[{"name1":"value1","name2":"value2"},{"name1":"value1","name2":"value2"},{"name1":"value1","name2":"value2"}]
I then handle this by using
var data = JSON.parse(json);
then, once doing this, I call this in a loop
data.item(i);
or using the function
data.splice(i, 1);
giving me the error
data.item is not a function
or
data.splice is not a function
I'm pretty certain that this is because it is not a true javascript array, but I haven't found anything that has told me how to convert it to one
EDIT I was actually looking for the .item() function used in NodeList (from things like getElementByClassName) however, this does not solve my issue with .splice

Your JSON is invalid - it needs commas separating the objects:
[{"name1":"value1","name2":"value2"},{"name1":"value1","name2":"value2"},{"name1":"value1","name2":"value2"}]
Parse the JSON like you were:
var data = JSON.parse(json);
And to access each object, use the index of the array:
var element1 = data[0]; // first element
var element2 = data[1]; // second element
etc.
And to access the values in the objects:
var name1 = data[0].name1; // value1
or even, since you've already defined the element1 variable:
var name1 = element1.name1;
If you're using a loop:
for (var i = 0, l = arr.length; i < l; i++) {
console.log(data[i]);
}

Once you've run data = JSON.parse(json), you can verify that data is an array using either data instanceof Array or Array.isArray(data).
In this case, both should be true, because you do have an array. JS arrays simply don't have an item method (that is, Array.prototype does not have a property item that is set to a function, or in fact, an item property at all), so you're trying to call something that does not exist.
To access an element from an array, you use the arr[n] syntax with a number. This is how you retrieve elements, not calling item.
While parsing, if your JSON is invalid, an exception will be thrown. You should wrap the JSON.parse call in try { ... } catch block to safely handle that.
All together, your code would look something like:
try {
var data = JSON.parse(json);
if (data && data.length) { // make sure data is a real thing and has some items
for (var i = 0; i < data.length; ++i) {
console.log(data[i]); // using [] to access the element
}
}
} catch (e) {
console.error('Parsing JSON failed:', e);
}

Related

I have an issue with removing an object key with a for in loop

I'm using a for x in loop to check if a value is == to [] and if so remove the property using remove but it just does not seem to work.
const whosOnline = (a) => {
var obj = { online:[],
offline:[],
away:[] };
for(let i = 0; i < a.length; i++){
if(a[i].lastActivity > 10 && a[i].status == 'online'){obj.away.push(a[i].username)}
else if(a[i].status == 'offline'){obj.offline.push(a[i].username)}
else{obj.online.push(a[i].username)}
}
for(let x in obj){
console.log(obj[x])
if(obj[x] === []){delete obj[x]}}
return obj
}
you were close, however you also need to reference the array index for each object key value. Comments explaining this in the code below.
var obj = { online:[],
offline:[],
away:[] };
for(var x in obj){
if(!obj[x][0]){ // The 0 is the index inside the online array, next loop it will be the offline array and then the away array.
console.log('The array is empty');
// Do what you want to do now that it is empty
// This will continue to loop through and check the value of all the keys in the object.
}
}
console.log('done');
Good luck -
Mitch from
https://spangle.com.au
Using some debugging (simply testing if a console.log gets printed for instance) you find that your if-condition is never true.
This is because you test if an array equals a newly created empty array. This can never be the case, because objects are compared by object reference instead of value.
Instead you want to probably test to see if your array is empty by doing ‘if(obj[x].length===0)’ (or shorter: ‘if(!obj[x].length)’)

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]
}

Weird behavior of javascript

Please see attached screenshot. See pendingApp property of Object. when I am debugging in eclipse then pendingApp show array of object, Which is correct! But when I am JSON.stringify(object) then showing me empty Array.
Please let me know reason of this behavior. I think I am not aware with any Java-Script thought/concept ?? :P :)
When I will save this Object into DB then blank array of pendingApp will be stored !!
var pending_app = [];
var new_record = {"pendingApp" : [], "installedApp" :[] };
....SOME CODE+conditions HERE....
pending_app[appId] = {'action' : action };
new_record.pendingApp = pending_app;
// create app-config data
return app_model.create(new_record); //will return promise object
It's not a weird behaviour but a common mistake of using an Array to store key-value data.
Short Answer : Use a literal Object to store these data
While you can add properties on every objects in Javascript, you cannot iterate over them with the default array mechanisms
for (var i = 0; i < array.length; i++){}
array.forEach();
Simple demonstration :
var array = [];
array["anId"] = 1;
array.length; // 0
array[4294967295] = 1; // Indice >= unsigned 32-bit Max Value
array.length; // 0
array[4294967295]; // 1
So JSON.stringify with the ECMAScript 5 Specification will use the Array mechanism to iterate over all items and will find nothing.
Unlike Objects that you can list properties with
Object.keys(array); // ["anId"]

Why for-in iterates through array methods also?

on a page I use similar syntax to google analitycs code, to pass parameters to another script. I iterate through the array and try to construct query part of URL according to the parameters in the included script.
The problem is the following iterates through the javascript array objects methods also and mess up resulting queryString.
index.html:
<script>
var params = [];
params['first'] = '1';
params['second'] = '2';
(function() {
var vs = document.createElement('script');
vs.async = true; vs.type = 'text/javascript';
vs.src = 'http://my.domain.com/js/includedScript.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(vs, s);
})();
</script>
includedScript.js:
function(paramsArray) {
tmpArray = [];
for(i in paramsArray) {
tmpArray.push(i + '=' + escape(paramsArray[i]));
}
var queryString = tmpArray.join('&');
}(params);
I got (shortened):
queryString == 'first=1&second=2&push&$family=function%20%28%29%20%7B%0A%20%20%20%20return%20lower%3B%0A%7D&$constructor=function%20Array%28%29%20%7B%0A%20%20%20%20%5Bnative%20code%5D%0A%7D&pop=function%20pop%28%29%20%7B%0A%20%20%20%20%5Bnative%20code%5D%0A%7D&push=function%20push%28%29%20%7B%0A%'
I expect:
queryString == 'first=1&second=2'
It's strange, that on my localhost blank page it's working well. Could some other javascript on the index.html page collide with my code? How can I fix the collision by changing only my code (preferably only the includedScript.js file)?
Thanks in advance.
One small change:
var params = {}; // notice the difference here!
params['first'] = '1';
params['second'] = '2';
and another one here
for(i in paramsArray) {
if(paramsArray.hasOwnProperty(i)){
tmpArray.push(i + '=' + escape(paramsArray[i]));
}
}
JavaScript's Array should only be used with numeric indexes. For associative arrays use Object instead. Also to make sure that the properties you get were added by you and do not belong to the a prototype use hasOwnProperty.
See the documentation on mozilla.org for more info.
An array is an ordered set of values
associated with a single variable
name. Note that you shouldn't use it
as an associative array, use Object
instead.
Also you could read this article:
http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
Note: The for ... in JavaScript construct has no connection with Array. Its purpose is to iterate over Object properties, not Array elements. In JavaScript properties also include methods.
Fun with JavaScript.
Try the following code and tell me if you're surprised:
var x = [];
x['one'] = 1;
x['one'] = 2;
alert(x.length);
then try this one:
Object.prototype.myProp = 123;
var x = {one: 1, two: 2}
for(var prop in x){
alert(x[prop]);
}
You want to do this
for (i in paramsArray) {
if (paramsArray.hasOwnProperty(i)) {
....
}
}
You should not use for..in to iterate through array elements. Things can be prototyped onto an object automatically to make use of DOM methods or programatically by other javascript on a page (like prototyping).
You should instead get a count of array elements using .length and a normal for loop.
var l = paramsArray.length;
for (var c = 0; c < l; c++) {
// do stuff
}
duncan's answer is correct, and that is because the for-in loop treats the paramsArray as an object, not an array.
And as Alin mentioned, use for (var i = 0; i < paramsArray.length; i++) for arrays.
This is usually an issue when looping using for...in, which is never really recommended.
A way around it is to use the .hasOwnProperty() method to ensure you are getting your own variables:
for (var k in foo) {
if (foo.hasOwnProperty(k)) {
// do something with foo[k]
}
}
Or as others have suggested, use a regular for loop:
for(var k = foo.lenght-1; k >= 0; --k) {
// do something with foo[k]
}
Which is more efficient (especially when reversed)
I love Array.forEach(). It takes a function as an argument. That function receives the element, index, and original list as arguments.
["a","b","c"].forEach(function(item, index, list)
{
console.log("the item at index " + index + " is " + item);
});
To make it compatible with older versions of IE, see here.

Categories

Resources