Working with a JSON file and Javascript - 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([])

Related

Is it possible to execute a Javascript function after a specific console.log() entry?

I'm working with a very limited web platform which makes use of 3rd party Javascript libraries. Without listing the extraneous details of how and why it operates the way it does, I'm curious if it is possible to do something/anything (e.g. execute Javascript function) after a specific console.log entry appears. The system is very locked down but I'm trying to improve the overall user experience of the application.
A typical console log entry from this Javascript library usually looks like this:
data access_token=XXXXXXXXXXXXXXXX&type_name=user&attributes=["uuid","displayName","email"]
Googling yields a large amount of unrelated results. I found this which involves overwriting the console.log method but that's not my desired approached: How to get the console.log content as string in JavaScript
Any ideas? I'm assuming you convert the current contents into an array or string and parse for results.
You can override console.log() AND, keep it still logging to the console so you can both capture the output and leave logging in place.
Here's a way to do that:
var logEntries = [];
(function(oldLog) {
console.log = function(arg) {
// captures only first argument to console.log()
// could be expanded to concatenate all entries
logEntries.push(arg.toString());
// now call original console.log() with original arguments
return oldLog.apply(console, arguments);
};
})(console.log);
So, now at any given time, the logEntries variable will be an accumulated array of everything sent to console.log(). This is a simple version that does not expand objects or enumerate arrays. More features in that area could be added, but it appears you're just looking for a specific string.
You could also add any filtering before adding to the logEntries array if you only want to capture things containing "access_token", for example.
If you wanted to only capture the lines that contain "access_token=", then you could modify the above code like this:
var logEntries = [];
(function(oldLog) {
console.log = function(arg) {
if (typeof arg === "string" && arg.indexOf("access_token=") !== -1) {
logEntries.push(arg);
}
// now call original console.log() with original arguments
return oldLog.apply(console, arguments);
};
})(console.log);

fail to get json object in javascript from php

I am trying to pass json string to javascript from php, so at first i did
<div id="picker" data-dates=\''.json_encode(unserialize($a->available_datetime)).'\'></div>
and then, i try to grab it in jquery
if($("#picker").length){
available = $("#picker").attr("data-dates");
}
However, it seems it then fail to loop through the object to get key and val
$.each(available,function(key,val)
{}
It keep getting error of
var length = !!obj && "length" in obj && obj.length,
Tried for several hours now, cant find a solution to solve. Anyone can help? Thanks.
Use $("#picker").data("dates") it will get the data stored in the attribute data-dates and convert it to JSON, assuming you have a JSON string in that attribute.
Then use:
for (var i in available) {
//do something with available[i]
}
check example: https://jsfiddle.net/fud6sfjo/

output individual values from one key JSON jQuery

I'm trying to output values from an array that has one key and multiple values in a JSON file. I've managed to output the values using $.each(), but what happens is that the value is returned as an array, because it is an array! I want to output each value individually so that the output is not an array:
<img src="one-value-output" />
<img src="two-value-output" />
etc...
JSON
var dataJson = "http://www.reneinla.com/kris/scripts/print.json";
The JSON file looks like this:
{
"printImages":[
"http://reneinla.com/kris/images/print/2008-06_KZO_TEN_01.jpg",
"...",
"http://reneinla.com/kris/images/print/2008-06_KZO_TEN_03.jpg"
]
}
JAVASCRIPT
var dataJson = "http://www.reneinla.com/kris/scripts/print.json";
//var dataArr = $.parseJSON(dataJson);
$.getJSON(dataJson, function (data) {
$.each(data, function (k, v) {
console.log( v );
});
});
I'd like to be able to output each value and append it to an src attribute, but wanted to see the console.log output first.
First Question
How do you print out, console.log, all the values from the json file?
Second Question
Is this the right approach to what i'm trying to achieve? I thought I'd use a JSON file because I have 88 values that need to be appended into the DOM. I could make the JSON file into an object, in my js file, but wanted to keep it more organized and efficient. This is still fairly new, so any insight here would be appreciated. Thanks and regards!
EDIT
I was able to get my desired result using this code:
var dataJson = "http://www.reneinla.com/kris/scripts/print.json";
//var dataArr = $.parseJSON(dataJson);
$.getJSON(dataJson, function (data) {
$.each(data, function (k, v) {
var i = 0;
for (i; i < v.length; i++){
console.log( v[i] );
}
});
});
Hooray!
Looking at your JSON, what you have is an object with 1 property, which is an array of strings.
Using developer tools, you should set a breakpoint inside the $.getJSON success callback function to inspect the value of data. You'll see that data is not an array, but that you should actually be going after data.printImages. Otherwise, your code looks OK to me.
Re: Your approach. It seems like a good idea to me. Some day you might change the static .json file out for a server processed file, and you probably wouldn't have to change the client side at all to do that, other than point at a different URL.

I'm unable to count the length of an Object

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.

Checking if an element exists in json

using the following feed:
http://api.twitter.com/1/statuses/user_timeline.json?screen_name=microsoft&include_rts=1&count=10
I am successfully able to loop through this to get the details I want to display on my html page.
However, I need to check if retweeted_status.user.profile_image_url exists, and I am not sure how to do that?
Currently I am looping through the data where data is returned by jquery-ajax:
data[i].retweeted_status.user.profile_image_url
if data[i].retweeted_status.user.profile_image_url does not exist, it does not return null or undefined, I just get the following error:
cannot read property 'user' of undefined
That error message suggests that either your data[i] or your retweeted_status is undefined, which means your call to get the json is most likely failing. WHen data is returned from Twitter it will aways have a profile image url, because they show an egg-like image for those with none uploaded. You should put this before your for loop:
if (typeof(retweeted_status) != "undefined")
{
//code for what to do with json here
}
I think it's a good answer:
if('key' in myObj)
if (something !== undefined) {
...
}
... or even better:
if (typeof something != "undefined") {
...
}
If you are looping and accessing nesting objects:
if(!data)
return;
while(data.length)
{
var tweet_data = data.shift();
/* do some work */
if(!tweet_data|| !tweet_data.retweeted_status)
continue;
var retweeted_status = tweet_data.retweeted_status;
/* do your other work */
}
This loop no longer needs to use array indexes, which isn't the most efficient unless you specifically need the index for something. Instead, it pops the first element off the array and using that object directly. The loop internals can then check the existence of a property on tweet_data.
I try to avoid using more than 1 level of dereferencing for 2 reasons (like objA.child.property):
1) You can check the existence of an object from the start and if it doesn't exist, jump out or assign default values.
2) Everytime JavaScript needs to access the method property, it first has to find child withing objA and then access property. Could be slow in large loops.
Take a look at $.grep(). It helps you loop through JSON objects. I used it on the link you provided. I used it to loop through the tweets and find the retweeted user images. You can have a look at my code here:
http://jsfiddle.net/q5sqU/7/
Another thing you can do, which has worked for me:
if(retweeted_status) {
// your code
}

Categories

Resources