What is the problem here?
First example:
console.log(ntags);
console.log(JSON.stringify(ntags));
Console output (Google Chrome):
[Array[0], Array[0]]
0: Array[0]
length: 0
numerical_value: null
tag_id: "3"
1: Array[0]
length: 0
numerical_value: "12"
tag_id: "5"
[[],[]]
Obviously the variable "ntags" is populated with a certain number of associative arrays which have certain values. However JSON.stringify makes an empty array.
Second example - the same problem occures if I try to post the variable ntags with Ajax directly:
$.ajax({ type:"POST", url: "/?tag_connection=update&fdata_id="+save_id, data: {cons: ntags}, success: function(result){
...
});
The client does not send any post data to the server side ($_POST empty in PHP).
JSON serialising does not serialise properties of an Array, this is simply not the expected behaviour - an array is a list of values, in order. The properties for this do not get serialised simply because it is not expected behaviour. You could technically serialise this, but it would defeat the point of having an Array as a data type.
For example, let's say we serialise the array [1,2,3,4] - then the expected output in JSON is:
[1,2,3,4]
simply because of it's type. If arrays were serialised like objects, the output might look something like this:
{0:1,1:2,2:3,4:4,length:4}
As you can see this is much longer - which means more data you need to send over a network, and a custom object to be created in any other programming language. This way we all agree on arrays.
So in this instance, you might just want to use an object, which will output the expected value. Try serialising this:
[{length:0,numerical_value: null, tag_id: 3}, {length: 0, numerical_value: null, tag_id:2}]
Related
So, I have a similar situation as with this question which "SHOULD" work but doesn't
How can I access and process nested objects, arrays or JSON?
My JSON is basically this... reduced for brevity.
NOTE:
"{"message": [{"id":"1","element1":"Something","element1":"Something"},{"id":"2","element1":"Something","element1":"Something"}],"status": "success"}"
What happens is that if I select response coming from the API, I get the entire JSON.
If I type: response.message, I get UNDEFINED. That makes absolutely no sense.
This is what it looks like in sessionStorage:
I just want to do what I've always done: response.message or response.whatever to just give me what's "INSIDE" message and for some reason, no matter what I do, it's not working.
Here's the part of the code where I get the response with message
globalService.commonService('getData', reqPkg).then((response) => {
$scope.theReport.data = JSON.parse(response);
});
if I do this I get undefined
$scope.theReport.data = JSON.parse(response.message);
I've tried JSON.stringify too, same result.
This is from a previous question which works fine and is in deed just the Objects from the Array of Objects.
const arrResult = Object.keys(objCount).map(k => ({'name': k, 'displayName': k, 'count': objCount[k] }));
$scope.theReport.data = JSON.parse(response).message; to get all entries from message into $scope.theReport.data.
Your response is a string, so parse the response and just grab the message key from that.
Sometimes in my project I'm using an JSON.Stringify to read data when I'm loging values to console, and sometimes I dont need to do it.. I'm wondering why?
In this example:
this._productServices.getAll().do(data => console.log(data)).subscribe(products=> this.articles= products);
And when I look at the console, there are values like this:
(4) [{…}, {…}, {…}, {…}]
Acctualy there is readable array of values.
But in this case:
filteredSubProducts: Group[];
filterSubProductsByIdId(Id) {
this.filteredSubProducts= this.articles.filter(item => item.parentId == Id);
console.log("Products array" + this.filteredSubProducts);
}
I get results as :
Products array[object Object],[object Object]
So I need to use JSON.stringify() in seconds case to get my values [object Object],[object Object] readable.. and I'm wondering why is that? Sometimes I'm using it and sometimes I'm not..
Thanks
You are getting it because you are adding a string "Products array" to an Array filteredSubProducts.
So the code is actually doing
console.log("Products array" + this.filteredSubProducts.toString());
The toString() method is causing the [object Object].
The way around it is to not concatenate, but use a comma in the console.log statement
console.log("Products array", this.filteredSubProducts)
Now it will allow you to show it without using JSON.stringify()
Now what is great about JSON.stringify() is it will give you the snapshot at that time. There are times when you change the array, object and it shows up in the console as the wrong value do to lazy evaluation. The stringify, causes it to be evaluated and you see it at that moment in time.
Because if you try to place an Object with a string Chrome will not parse the contents. If you need to "say" something before write an object or array to console you have to do it in two console commands or adding a comma
var myArray = [{content:"hola"}, {content:"hello"},{content:"hallo"}];
console.log("This does not work " + myArray);
console.log("This will work just ok");
console.log(myArray);
console.log("this works too" , myArray);
This is because you are joining together a string "Products array" with an object with .toString() - another string. What you see in console is string. Otherwise whole object gets logged. Try
console.log("Products array", this.filteredSubProducts);
Edit: Just removing the toString() does not do the trick, because everything that is after "string" + ... gets converted to string first.
// does not work
console.log("Products array" + this.filteredSubProducts);
That behaviour is called type coercion and you can read about it in this SO answer, in this article or just google it google it for more info
If you convert you response to JSON in your service, Then you have to stringify when you want to use that response.
res => res.json() // In this case you will need to use stringify
console.log() only works till 2nd level of nesting, for example if I run console.log({}, {}, {}), all of the objects in array will appear without any obfuscation, however if I try to log
console.log([
{},
{},
{a: {
a: {
a: {}
}
}}
])
The result will be something like [ {}, {}, { a: { a: [Object] } } ]
You can still view the objects by expanding them in any decent browsers console but terminals don't have that facility, so in order to view the nested items we use JSON.stringify() to convert the object and its children to string which can then be easily printed but you might have noticed they loosed their indentation in that way, because you are basically printing a string.
Within Jquery I am creating two arrays, one embedded in the other, like so....
arrayOne = [{name:'a',value:1}, {name:'b',value:2}]
var arrayTwo = [{name:'foo',value:'blah'},{name:'arrayOne',value:arrayOne}];
I am then putting this though Ajax and extracting the variable via PHP on the other side. The results of a print_r($arrayTwo) are as follows...
Array([foo] => blah [arrayOne] => [object Object],[object Object])
I can see no way of extracting the contents of arrayOne, which is a pity because I really need them! Can anyone tell me what I am doing wrong in Jquery or what I need to do in PHP to make the embedded array accessible.
Many thanks as always
Edit to add my Ajax code....
$.ajax({
type: "POST",
url:'actions.php',
data:arrayTwo,
datatype:'json',
cache: false,
success: function(data){
}
})
The issue is that jQuery's $.ajax (or rather $.param) method treats an array of objects in a special way. jQuery will use name as the parameter name and the string representation of value as value:
> $.param([{name: 'foo', value: 42}, {name: 'bar', value: 21}])
"foo=42&bar=21"
But the string representation of arrayOne is the useless stuff you are seeing on the server:
> [{name:'a',value:1}, {name:'b',value:2}].toString()
"[object Object],[object Object]"
The documentation actually points out the caveats when passing an array / object:
If the object passed is in an Array, it must be an array of objects in the format returned by .serializeArray()
[
{ name: "first", value: "Rick" },
{ name: "last", value: "Astley" },
{ name: "job", value: "Rock Star" }
]
Note: Because some frameworks have limited ability to parse serialized arrays, developers should exercise caution when passing an obj argument that contains objects or arrays nested within another array.
Note: Because there is no universally agreed-upon specification for param strings, it is not possible to encode complex data structures using this method in a manner that works ideally across all languages supporting such input. Use JSON format as an alternative for encoding complex data instead.
Since you have a complex data structure, you should probably use JSON to encode your data:
data: {data: JSON.stringify(arrayTwo)},
and on the server you simply decode it with
$data = json_decode($_POST['data'], true);
$data will have the exact same structure as arrayTwo.
But in case you want to actually have parameters with names foo and arrayOne, then you only need to serialize the the value of arrayOne:
data: [
{name:'foo',value:'blah'},
{name:'arrayOne',value: JSON.stringify(arrayOne)}
],
and in PHP:
$arrayOne = json_decode($_POST['arrayOne'], true);
Here's my problem, I make an ajax call, get a response:
$.getJSON('fpCustom.cfc?method=getSysCounts',function(data){buildChart(data);});
I get a JSON reponse. Raw result:
{"COLUMNS":["ABC","DEF","GHI"],"DATA":[[11,27,4]]}"
When I ask for COLUMN[0], I get correct value: 'ABC', but when I ask for DATA[0], I get the whole DATA string: 11,27,4. I think it probably has to do with the double square bracket, but don't know how to fix that.
How do I get DATA[0], which should be 11?
For the JSON:
{"COLUMNS":["ABC","DEF","GHI"],"DATA":[[11,27,4]]}"
The property DATA is an array of arrays.
Consider it like this: DATA = [a, b, c], where a, b and c are variables. The thing is that your a is another array, just as DATA is.
This way DATA[0], the first element of the DATA array, is an array.
How do I get DATA[0], which should be 11?
The value you want is in: DATA[0][0]:
Because:
DATA[0] -> [11,27,4]
Then:
DATA[0][0] -> 11
DATA[0][1] -> 27
DATA[0][2] -> 4
{"COLUMNS":["ABC","DEF","GHI"],"DATA":[[11,27,4]]}"
In COLUMNS is single dimentional array and DATA is two dimentional array so you have to access value of DATA[i][j]
check example
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.