I'm unable to count the length of an Object - javascript

In an ajax call i retrieve a JSON object and count the number of result throught lenght property. But in another code, with same kind of call and little modifications to the server-side script, the length propertu retrieve me alway undefined. Why?
Note that in the developer console the msg is treated like an object (i tink, converted automatically from JSON by ajax), not such an array.
$.ajax({
url : 'richiediListaVideo.php',
type : 'POST',
data : data,
dataType : 'json',
success : function (msg)
{
alert(msg['videos'].length)
},
The object whose "undefined" length is something like
-video
--title
--duration
---tags
---8 "funny"
---1352 "animals"
---13 "Tv"
My goal is to retrieve the tags length, and i wrote msg['video']['tags'].length
This is the stringfied version of "msg"
{"video":{"duration":"5:51","views":"2650","video_id":"512498","rating":"5.00","ratings":"5","title":"Lovely dog", "publish_date":"2013-08-05 16:50:08","tags":{"8":"funny", "54":"lol","75":"Animals","89":"Garden"}}}
Clarification:
Anyway i know how count the number of tags, but the point is that i really want to know why happen this
Anyway i know how count the number of tags
var length=0;
for(var elemy in res['video']['tags']) length++
but the point is that i really want to know why happen this

This is your result:
{"tags":{"8":"funny", "54":"lol","75":"Animals","89":"Garden"}}
That is why you will not be able to use .length.
If you had something like this LOOK AT THE DEMO:
var res =
{ "tags": [
{"8":"funny"},
{"54":"lol"},
{"75":"Animals"},
{"89":"Garden"}
]}
Then .length would work on res['tags'].length.

Anyway i know how count the number of tags
var length=0;
for(var elemy in res['video']['tags']) length++
but the point is that i really want to know why happen this
The reason that this happens is because res['video']['tags'] is an object defined with braces {...} and so it does not possess a length property since it is not a proper array. Proper arrays (one way of defining them is using square braces []) do have a length property.
Note: Named properties (i.e., not indexed by a whole number) are not counted as part of the length of an array, but can also be added to an array. And vice versa--numbered properties can be added to an object.

Related

What is the best way to itterate over key value pairs nested in an index using javascript?

I am trying to sort sets of associated key value pairs. They look like this:
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
But organized into labeled subsets of preferably a string or perhaps an index if necessary.
The data-set is a vote-per-use table of most used english words being parsed into pages.
I will be appending them as text to other html elements due to the constraints my use case, makes it a bit tricky, however, for an example I could work with a simple console.log of the page value followed by the console.log of every word value stored within that page. I need the order preserved. so probably indexed. I will also need to be able to sort each page by the votes value, but I think I can figure the rest out for that.
I have found tutorials on how to search through key-value pairs, but I cannot find how to do all of the following with one solution:
A: access the value of word
B: maintain the order of the data-set, allowing me to append them to the matching html element
C: allows me the opportunity to change which set of elements I am appending to when i have finished looping through a single member of the parent index (the one recording the page)
I imagine it is some combination of for/of and for/in, but I'm getting a headache. Please help?
addl info:
function would run at app startup or when the dataset being examined is changed.
function would take a large dataset filled with around 200 page number values, each with 60+ sets of data like the one listed above, the contents of a single page index for example:
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aaron","votes":4129,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abandoned","votes":1289,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abc","votes":5449,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aberdeen","votes":641,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abilities","votes":2210,"userMade":"FALSE","limiter":"FALSE"},
{"word":"ability","votes":7838,"userMade":"FALSE","limiter":"FALSE"},
{"word":"able","votes":8649,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aboriginal","votes":1837,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abortion","votes":3232,"userMade":"FALSE","limiter":"FALSE"},
{"word":"about","votes":9295,"userMade":"FALSE","limiter":"FALSE"},
{"word":"above","votes":8818,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abraham","votes":867,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abroad","votes":4969,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abs","votes":2415,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absence","votes":4934,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absent","votes":2937,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absolute","votes":5251,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absolutely","votes":5936,"userMade":"FALSE","limiter":"FALSE"},
{"word":"absorption","votes":285,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abstract","votes":7946,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abstracts","votes":1907,"userMade":"FALSE","limiter":"FALSE"},
{"word":"abuse","votes":7238,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academic","votes":7917,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academics","votes":1706,"userMade":"FALSE","limiter":"FALSE"},
{"word":"academy","votes":6755,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acc","votes":6469,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accent","votes":1020,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accept","votes":7547,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acceptable","votes":4907,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acceptance","votes":7273,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepted","votes":7684,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepting","votes":1789,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accepts","votes":1535,"userMade":"FALSE","limiter":"FALSE"},
{"word":"access","votes":9031,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessed","votes":2932,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessibility","votes":5702,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessible","votes":5662,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessing","votes":2096,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessories","votes":8875,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accessory","votes":5661,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accident","votes":5664,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accidents","votes":2991,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodate","votes":1807,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodation","votes":8059,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accommodations","votes":3885,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accompanied","votes":2532,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accompanying","votes":664,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accomplish","votes":1070,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accomplished","votes":2419,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accordance","votes":6434,"userMade":"FALSE","limiter":"FALSE"},
{"word":"according","votes":8282,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accordingly","votes":3003,"userMade":"FALSE","limiter":"FALSE"},
{"word":"account","votes":8996,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accountability","votes":3029,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accounting","votes":7459,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accounts","votes":7507,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accreditation","votes":1605,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accredited","votes":3027,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accuracy","votes":6779,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accurate","votes":6427,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accurately","votes":1493,"userMade":"FALSE","limiter":"FALSE"},
{"word":"accused","votes":2853,"userMade":"FALSE","limiter":"FALSE"},
{"word":"acdbentity","votes":1389,"userMade":"FALSE","limiter":"FALSE"},
and the output would ultimately append the value paired with each word to a specific button through iteration, but also sorted by the page value.
each page is a set of buttons in a 3d object that looks like this:
the text is appended to each button which in turn is a 3d object embeded in an html object using aframe. I can make the appending code.
You can use Object.entries() to get the key value pairs of an object.
var words = [
{"word":"a","votes":9326,"userMade":"FALSE","limiter":"FALSE"},
{"word":"aaron","votes":4129,"userMade":"FALSE","limiter":"FALSE"}
];
words.forEach((wordEntry) => {
var keyValuePairs = Object.entries(wordEntry);
keyValuePairs.forEach((kv) => {
console.log(`key: ${kv[0]} value: ${kv[1]}`);
});
});
my latest attempt looks like this:
for (let p=1; p<129; p++){
for (let b=1; b<68; b++){
let pTpl = (p).toLocaleString(undefined, {minimumIntegerDigits: 3});
let bDbl = (b).toLocaleString(undefined, {minimumIntegerDigits: 2});
var `#fCont${pTpl}${bDbl}` = document.createElement('a-text');
`fCont${pTpl}${bDbl}`.setAttribute('value', 'engWordLib[p,b,0]');
`fCont${pTpl}${bDbl}`.setAttribute('votes', 'engWordLib[p,b,1]');
`fCont${pTpl}${bDbl}`.setAttribute('userMade', 'engWordLib[p,b,2]');
`fCont${pTpl}${bDbl}`.setAttribute('limiter', 'engWordLib[p,b,3]');
`fCont${pTpl}${bDbl}`.setAttribute('visible', 'false');
`fBtn${bDbl}`.appendChild(`#fCont${pTpl}${bDbl}`)
}
}
please note that I havent checked this for errors. I still think this code is to WET and I would prefer the key names for the properties be preserved in the datastructure rather than tacked on when it's appended to the page. I guess I could add a dimension to the array.... seems kind of messy when an object property value has the key value pairs right in it. cant get the iteration of objects in an array down though.... Will continue to persue a cleaner method.

find value in complex object javascript

Basically I have a complex object that retrieves the GPT API (google publisher tag) with this function:
googletag.pubads().getSlots();
The object value is something like this:
I need to know if there is a way to compare the value of each property with an X value without getting a problem of recursivity (because the object is huge and i need to to that validation several times)
Also, I tried to convert that object into a JSON with JSON.stringify(), and then tried to get the value with a regex, faster, but with this option, I have the problem with Cyclic Object Value.
Any suggestions ?
it's more simple. try it to convert it into an array and later use a filter for comparative with your value.
var objGoogle = {};
var arrayObjectGoogle = [objGoogle];
var filter = arrayObjectGoogle.filter(function(obj){
obj.yourAttr == yourValue; });
this will give you a second array with the values found it. later, index the array for pick up the value do you need.

What's the fastest way to get all the initial values of a variable? JS

I want to get the initial values (What I first defined it to be) of all the properties for one of my objects.
I want to do this at the "end" of my game.
I could just copy and paste the properties but the object is pretty big and im wondering if this would slow the site down a bit?
Thanks!
Code example:
var MyObject = {
nestedObject1 : {
//...
},
nestedObject2 : {
value1 : "Hi",
value2 : 1
},
objectProperty : 2637
}
How would I get all (Or maybe excluding one of the nested objects) of the properties to their intial value?
I don't quite fully understand how you want to get the initial values, at the end of your running. But probably the easiest way to do this is to just serialize your object to JSON using JSON.stringify.
var original = JSON.stringify(myObject)
Then at the end of your application when you want access to this original object again you can rehydrate it to a new JavaScript object:
original = JSON.parse(original);

How to access data in JSON format using javascript

I'm trying to figure out on how to access data in JSON format and have gone a whole day searching for ways but I still can't find a solution to fit my needs. The closest relative question to my problem is this question but to no avail.
Basically I am retrieving data from $.ajax() which returns in JSON format.
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}]
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}]
My problem is how can I access the elements inside the JSON, say I want to get all values of "nv" or all values of "date" on the second bracket, in javascript? I Am new at things like these so am not familiar with the terminologies, sorry for that.
Below is my code:
var Data = $.ajax({
url: url,
type: 'POST',
dataType:"json",
async: false
}).responseText;
console.log(Data);
url is a variable that is passed inside my function in case you might ask.
Update: See Anthony Grist's comment on your question, I missed the fact that your JSON is invalid. Since he hasn't posted an answer, I'll pick it up.
Your JSON is invalid because you're returning two separate arrays, this one:
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}]
and this one:
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}]
You can't do that, because the top level of a JSON document must be one thing (an object or an array).
You could return an object with properties for each array:
{
"vdata":
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}
],
"datedata":
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}
]
}
After parsing (see below), you can access that data like this:
console.log(data.vdata[0].v); // "233"
console.log(data.datedata[0].date); // "2013-02-01"
Or an array with two slots, with each slot having one of your arrays in it:
[
[{"v":"233","pv":"1.83","avd":"00:01:58","nv":"82.83%","br":"75.11%"},
{"v":"17","pv":"3.65","avd":"00:08:31","nv":"70.59%","br":"58.82%"},
{"v":"9","pv":"2.22","avd":"00:01:51","nv":"0.00%","br":"44.44%"}
],
[{"date":"2013-02-01","visits":63},
{"date":"2013-02-02","visits":30}
]
]
After parsing (see below), you can access that data like this:
console.log(data[0][0].v); // "233"
console.log(data[1][0].date); // "2013-02-01"
Personally, I prefer using an object, since then it's clear which array I'm accessing.
Original answer:
jQuery will parse the JSON into an object for you and pass that to the success function, which you can then access just like any other object. In your case, the top level is an array. So:
$.ajax({
url: url,
type: 'POST',
dataType:"json",
async: false,
success: function(data) {
// Use the line from above that suits the way
// you updated your JSON structure
}
});
Side note: async: false is deprecated and will be removed at some point. It's generally not a good idea to do synchronous ajax requests, it tends to lock up the UI of the browser during the request. Instead, just structure your code to continue processing when the success callback is triggered.
If I understand your problem you need to access the same key for all objects in this array.
There is no direct method to do that, you have to iterate through all objects in this array and then find the desired key in each of those objects.
JSON.parse() will convert this string into a Javascript Object (JSON)
var myData = JSON.parse(Data);
for(var i = 0; i < myData.length; i++) {
console.log("This is the nv value of the " + i + " object: " + myData[i].nv);
}

Working with a JSON file and Javascript

On return of a JSON file I can't seem to be able to detect how many results are returned. The problem seems to be with the JSON file returning a diffrent number of items each time. At times it will return 1 item, then at other it will return more than 1. You see, I'm trying to get the very first result from the JSON file so I can display it. Now, If change the code everytime I know the number that will be returned, the following two bits of code work.. Artists.id; and Artists.id[0];, but I can't seem to make them work together, at the momment..
If 1 result is returned, Artists.id; will successfully bring back the artist ID;
If more than 1 result is returned Artists.id; will return "undefined".
So I need to change it to Artists.id[0]; if the JSON file returns more than 1 item. However when I change it to this, if the JSON conatins 1 item, it will return "undefined".
It seems I need some code to tell me if the returned array has 1 or more items. I've tried arr.length but that doesn't seem to be working (perhaps i miss-coded it). I also tried if(arr===undefined) and that failed to work too. The code below is what I have come up with, using the artistzero, but it is not working. Anyone has any advice? or a reason why the code below would not work?
Current Code:
$.ajax(
{
type: "GET",
url: id_url,
dataType: "jsonp",
success: function (responseData, textStatus, XMLHttpRequest)
{
if (responseData.Artists.Artist)
{
var Artists = responseData.Artists.Artist;
var artistzero = Artists.length;
if (artistzero >= 2)
{
// if more than one result is returned
var artisttype = Artists.id[0];
}
if (artistzero <= 1)
{
// if one result is returned
var artisttype = Artists.id;
}
}
else
{
$('body').append('No results');
}
}
});
Sample JSON with 1 result:
{"Artists":{"total":"1","count":"1","start":"1","errorCount":"0","Artist":{"id":"33291476","flags":"123010","catzillaID":"0","website":"","name":"Jamie T","rating":"-1","ItemInfo":{"Relevancy":{"index":"1316"}},"hotzillaID":"1809709440","url":"http://web.com/jamie-t/","trackCount":"96"}}}
Sample JSON with more than one result:
{"Artists":{"total":"1087","count":"3","start":"1","errorCount":"0","Artist":[{"id":"256212","flags":"123523","catzillaID":"1927205428","website":"http://www.bobmarley.com/","name":"Bob Marley","rating":"-1","ItemInfo":{"Relevancy":{"index":"718"}},"hotzillaID":"1802045595","url":"http://web.com/bob-marley/","trackCount":"12706"},{"id":"312874","flags":"124611","catzillaID":"1927580000","website":"http://www.bobdylan.com/","name":"Bob Dylan","rating":"-1","ItemInfo":{"Relevancy":{"index":"694"}},"hotzillaID":"1800021697","url":"http://web.com/bob-dylan/","trackCount":"4987"},{"id":"268472","flags":"41603","catzillaID":"1927193413","website":"","name":"Bob Wills","rating":"-1","ItemInfo":{"Relevancy":{"index":"644"}},"hotzillaID":"1800264434","url":"http://web.com/bob-wills/","trackCount":"2364"}]}}
You need to access the first artist before grabbing the id (since it's an array) like this:
var artisttype = Artists[0].id;
It would be better if you could change the JSON to always return an Array, even with one result...unfortunately some platforms don't do this, for reasons beyond my comprehension.
for(var propertyname in responseData){
//will loop through the different elements in your json array
alert(responseData[propertyName]); //will output the valueof each element
}
You're right that this is problematic, and to be honest it sounds like the "other end" that's sending you the JSON is being inconsistent.
The problem is that when there are multiple items they're sending you an array for the id property, and when there's a single item they're just sending you a simple value (e.g. an integer). Ideally, when there is a single item you should be sent a single-item array - this would let you use the same array-based parsing code every time.
If you can't convince them to change what they're sending you, though, then the best bet is simply to do what you're currently doing; see if Artists.id is defined, use it if so, else fall back to accessing id as an array.
However, if more than 1 result is returned Artists.id; will return "undefined". So I need to change it to this: Artists.id[0];
this cannot be Artists.id should be "object" not undefined if Artists.id[0] exists. Maybe it is as stated Artists[0].id ? and if so you could test typeof(Artists) == typeof([])

Categories

Resources