I get the following error in IE8:
length is null or not an object
Anyone have any ideas? Feedback greatly appreciated.
function refresh() {
$.getJSON(files+"handler.php?action=view&load=update&time="+lastTimeInterval+"&username="+username+"&topic_id="+topic_id+"&t=" + (new Date()), function(json) {
if(json.length) {
for(i=0; i < json.length; i++) {
$('#list').prepend(prepare(json[i]));
$('#list-' + count).fadeIn(1500);
}
var j = i-1;
lastTimeInterval = json[j].timestamp;
}
});
}
Just check for the object being null or empty:
if (json && json.length) {
// ...
}
C'mon gang this was glaringly obvious :-)
JSON objects (returned by jQuery or otherwise) do not have a length property. You'll need to iterate over the properties, most likely, or know the structure and simply pull out what you want:
$.getJSON( ..., ..., function( json ) {
for( var prop in json ) {
if( !json.hasOwnProperty( prop ) ) { return; }
alert( prop + " : " + json[prop] );
}
} );
Alternatively, grab a library like json2 and you'll be able to stringify the object for output/debugging.
pop the JSON in a span then clip it and paste it here so we can see it:
<span id="JSObject2">empty</span>
with the json2.js from here: (link for it at bottom of the page) http://www.json.org/js.html
myJSON = JSON.stringify(json);
$('#JSObject2').text(myJSON);
Using that, we can help you better, and you can see what you have!
What does your returned JSON look like? If you're returning an object, length might not be explicitly defined, whereas if you're returning an array, it should be defined automatically.
First thing that comes to mind is that length is not a property of whatever json is. What is the json variable supposed to be anyway?
A JSON is an object, you seem to be treating it like an array. Does it really have a length property? Show us the JSON?
You might need to use a for..in instead.
EDIT: Can you make the JSON from the backend structure like so?
({
"foo": []
})
Related
I'm parsing an order feed to identify duplicate items bought and group them with a quantity for upload. However, when I try to map the resulting array, it's showing [object Object], which makes me think something's converting the return into an object rather than an array.
The function is as follows:
function compressedOrder (original) {
var compressed = [];
// make a copy of the input array
// first loop goes over every element
for (var i = 0; i < original.length; i++) {
var myCount = 1;
var a = new Object();
// loop over every element in the copy and see if it's the same
for (var w = i+1; w < original.length; w++) {
if (original[w] && original[i]) {
if (original[i].sku == original[w].sku) {
// increase amount of times duplicate is found
myCount++;
delete original[w];
}
}
}
if (original[i]) {
a.sku = original[i].sku;
a.price = original[i].price;
a.qtty = myCount;
compressed.push(a);
}
}
return compressed;
}
And the JS code calling that function is:
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
The result is:
contents: [ [Object], [Object], [Object], [Object] ]
When I JSON.stringify() the output, I can see that it's pulling the correct info from the function, but I can't figure out how to get the calling function to pull it as an array that can then be mapped rather than as an object.
The correct output, which sits within a much larger feed that gets uploaded, should look like this:
contents:
[{"id":"sku1","price":17.50,"quantity":2},{"id":"sku2","price":27.30,"quantity":3}]
{It's probably something dead simple and obvious, but I've been breaking my head over this (much larger) programme till 4am this morning, so my head's probably not in the right place}
Turns out the code was correct all along, but I was running into a limitation of the console itself. I was able to verify this by simply working with the hard-coded values, and then querying the nested array separately.
Thanks anyway for your help and input everyone.
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
In the code above the compressedOrder fucntion returns an array of objects where each object has sku, price and qtty attribute.
Further you are using a map on this array and returning an object again which has attributes id, price and quantity.
What do you expect from this.
Not sure what exactly solution you need but I've read your question and the comments, It looks like you need array of arrays as response.
So If I've understood your requirement correctly and you could use lodash then following piece of code might help you:
const _ = require('lodash');
const resp = [{key1:"value1"}, {key2:"value2"}].map(t => _.pairs(t));
console.log(resp);
P.S. It is assumed that compressedOrder response looks like array of objects.
At the moment I am stuck with a problem that just seems stupid, but I don't know the answer to it.
I am trying to access this JSON-object:
var custom_fields =
{
"28246": 5123,5124,5125
}
I would like to get each value from that key. I would know how to access it if it was a nested-object, but it isn't sadly (it is coming from an API, which I can't change the JSON-response from sadly)
What I tried already is the following:
for (var key in custom_fields) {
if (custom_fields.hasOwnProperty(key)) {
console.log(key + " -> " + custom_fields[key]);
}
}
The problem here is that the result will be like this:
1 -> 5
2 -> 1
3 -> 2
4 -> 3
5 -> ,
6 -> 5
...etc...
Any suggestions are welcome, I am trying to access it in javascript/Jquery.
Thanks for helping in advance!
I assume that the data is in this format (note the string literals):
var custom_fields = {
"28246": "5123,5124,5125"
}
If that is the case, you can use String.split.
In your case, it would be something like this:
const values = custom_fields['28246'].split(',');
The values of they key 28246 are now stored in the new variable values as an array:
['5123','5124','5125']
If you want to parse all values to integers, I suggest using Array.map:
const valuesAsInt = custom_fields['28246'].split(',').map(value => parseInt(value);
Which will lead to this:
[5123, 5124, 5125]
Disclaimer: When using newer ECMAScript features such as Array.map, be sure to either use a browser which supports this our include a polyfill.
You can access it by using split function which will convert it into an array and then get the values from that array as below code.
var data = {
"28246": '5123,5124,5125'
}
var arr = data['28246'].split(',');
$.each(arr, function( index, value ) {
console.log(value);
});
You can split by ',' and transform each element to integer by using array.map and '+' operator:
var custom_fields =
{
"28246": "5123,5124,5125"
}
custom_fields["28246"] = custom_fields["28246"].split(',').map(el => +el);
console.log(custom_fields);
console.log(custom_fields["28246"][0], custom_fields["28246"][1], custom_fields["28246"][2]);
This is my JSON data ....
{"comp1":["$.Create_Keypair1_Keypair_name"]}
I want to get the value "Create_Keypair1_Keypair_name".but all the keys and values are dynamic.but the object always have single data.
I have Object.keys(temp).It shows only ["comp1"] i need
$.Create_Keypair1_Keypair_name only....
Try this:
var data = {"comp1":["$.Create_Keypair1_Keypair_name"]}
for (var key in data) {
console.log(data[key])
}
This will log $.Create_Keypair1_Keypair_name.
From what I am understanding each object will have a single value. If the is the case then you do not need the array in the object. You can do this.
var tempy = {"comp":"ksmdfnsfdnsdfn"}
Then do this to ge the value.
tempy.comp
Or if you need the keys.
Object.keys(tempy)
you might be looking for this
var temp = {"comp1":["$.Create_Keypair1_Keypair_name"]}
Object.keys(temp).forEach(function(key){
console.log(temp[key]);
});
please i have this output from my json web service:
{"format":"json",
"success":true,
"errors":[],
"result":
{"**206**":
{"player_name":"stagiaire",
"M":{
"6480":{"score":0,"answer":"cdgvbdbgd","category_name":"cdgvbdbgd"},
"6481":{"score":0,"answer":"cdgvbdbgd","category_name":"cdgvbdbgd"},
"6482":{"score":0,"answer":"cdgvbdbgd","category_name":"cdgvbdbgd"},
"6483":{"score":0,"answer":"cdgvbdbgd","category_name":"cdgvbdbgd"},
},
"O":{
..... },
}
}
}
What i want is to extract the value (which is now 206 but it can be another number).
I am asking for your help to achieve this goal.
Any help will be appreciated.
In case the resulting object contains only a single property with this number as its name, i.e.
result = {
206 : {
...
}
// no other properties here
}
then you can use something like:
var num = Object.keys(result).shift(); // "206"
Check the browser compatibility for Object.keys() method at MDN and use shim if needed.
If the object you look for always has a player name as value, try
for (var key in obj.result) if obj.result[key]["player_name") alert(key)
Or use jQuery
$.each(data.result,function(key,val) {
alert(key);
});
It sounds a lot more complicated than it really is.
So in Perl, you can do something like this:
foreach my $var (#vars) {
$hash_table{$var->{'id'}} = $var->{'data'};
}
I have a JSON object and I want to do the same thing, but with a javascript associative array in jQuery.
I've tried the following:
hash_table = new Array();
$.each(data.results), function(name, result) {
hash_table[result.(name).extra_info.a] = result.(name).some_dataset;
});
Where data is a JSON object gotten from a $.getJSON call. It looks more or less like this (my JSON syntax may be a little off, sorry):
{
results:{
datasets_a:{
dataset_one:{
data:{
//stuff
}
extra_info:{
//stuff
}
}
dataset_two:{
...
}
...
}
datasets_b:{
...
}
}
}
But every time I do this, firebug throws the following error:
"XML filter is applied to non-xml data"
I think you can use the JSON response as an associative array. So you should be able to go directly in and use the JSON.
Assuming you received the above example:
$('result').innerHTML = data['results']['dataset_a']['dataset_two']['data'];
// Or the shorter form:
$('result').innerHTML = data.results.dataset_a.dataset_two.data;
Understand that I haven't tested this, but it's safer to use the square brackets with a variable than it is to use parenthesis plus the name with the dot accessor.
Your example is failing because of some convoluted logic I just caught.
$.each(data.results), function(name, result) {
hash_table[result.(name).extra_info.a] = result.(name).some_dataset;
});
Now, the foreach loop goes through the variable data.results to find the internal elements at a depth of 1. The item it finds is given to the lambda with the key of the item. AKA, the first result will be name = "datasets_a" item = object. Following me so far? Now you access the returned hash, the object in item, as though it has the child key in name ... "datasets_a". But wait, this is the object!
If all else fails... write your result JSON into a text field dynamically and ensure it is formatted properly.
Why would you want to change an array into another array ?-)
-- why not simply access the data, if you want to simplify or filter, you can traverse the arrays of the object directly !-)
This works. Just dump it into a script block to test.
d = {
'results':{
'datasets_a':{
'dataset_one':{
'data':{
'sample':'hello'
},
'extra_info':{
//stuff
}
},
'dataset_two':{
///
}
///
},
'datasets_b':{
///
}
}
}
alert(d.results.datasets_a.dataset_one.data.sample)
I hope this pasted in correctly. This editor doesn't like my line breaks in code.
d = {
'results':{
'datasets_a':{
'dataset_one':{
'data':{
'sample':'hello'
},
'extra_info':{
//stuff
}
},
'dataset_two':{
///
}
///
},
'datasets_b':{
///
}
}
};
alert(d.results.datasets_a.dataset_one.data.sample)