JSON stringify outputs empty object for not empty object [duplicate] - javascript

I need to convert to a JSON value the result of a DOMRect object returned by Element.getBoundingClientRect()
Here an example:
http://jsfiddle.net/5vs6x6fc/2/
When using JSON.stringify() it returns {}, I need the JSON value instead.
I would like to know:
Why is that?
What could be a possible solution alternative to looping to the property of the returned object r ex: for (var property in r){}
Notes: I am targeting Chrome.

Bounding rect only contains "virtual" properties. If you
console.log(Object.getOwnPropertyNames(r));
// or
console.log(Object.keys(r));
you'll get an empty list. JSON.stringify() depends on Object.keys(r) (see comments below) and thus returns an empty object literal.
Your loop-based approach seems to be a feasible solution to this problem.

Related

Pass array to function by value [duplicate]

This question already has answers here:
JavaScript: How to pass object by value?
(14 answers)
Closed 5 years ago.
This is my first function, i pass to json
end if it is the first time i save the json is original.
function loadchart2(div, json, lista,tipo) {
var listaId = lista;
if(l==0){
jsonSecCall =JSON.parse(JSON.stringify(json));
listaSecCall=listaId;
l++;
}
I modify json ,and click a button.
Call second function and call loadcart2 and pass the json original but actually receives the json modify, What???
$("#giorni").on('click',function () {
var nuova=jsonSecCall;
$("#svgDateLine2").remove();
loadchart2("content", nuova,listaSecCall,"giorni");
checkContainer();
});
Probably the json it is gone for reference, is possible??
This is an example https://jsfiddle.net/tsjvmsd0/.
First console log print json modified, is ok, the next console log they should
print the original json, but print json modified.
This is the con of javascript. Everything in JS is passed by value, except objects, due to they are collections of references. That was done in performance reasons - it is costly to make copy of whole object.
To modify object without mutating the original, you should copy it. One way is to use Object.assign. It's probably better than making so deep copy of object ;-)
Then the snippet will be
var copy = {}
Object.assign(copy, source)
I dont know the types of your variables but normally I use Array.prototype.slice for copying.
var a = [1, 2, 3];
var b = a.slice(0); //Creates a new array
For copying objects see #alexcleac answer.
Firstly, it doesn't look like you are dealing with JSON, it looks like you are dealing with an object (or an array). JSON is a string.
Secondly, you aren't passing in the original JSON to loadchart2 (as you have figured out). You already modified the object reference by the variable jsonSecCall
What you probably want to do is actually maintain the original JSON (string) form of the object and use that as your original, unmodified object. You can do a JSON.parse on it whenever you want an object reference of your original.

JSON.stringify and non associative array

I want to serialize in json a non associative array and the output is quite disturbing
JSON.stringify([1]);
// Expected : "[1]"
Output : "\"[1]\""
It treats the array as a string, what am i missing ?
I'm using Chrome Version 29.0.1547.65
The issue you are seeing is because of an Array.prototype.toJSON method that has been defined incorrectly with respect to the semantics of JSON.stringify. See below:
From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
toJSON behavior
If an object being stringified has a property named toJSON whose value
is a function, then the toJSON method customizes JSON stringification
behavior: instead of the object being serialized, the value returned
by the toJSON method when called will be serialized.
When an object has a toJSON method the result of that method will be stringified in its place. If the toJSON method is defined as a stringification then the object will be double stringified.
The only work-around I am aware of is to remove the method or to implement your own stringify() method with different semantics than the built-in.
If you can, simply remove the method from Array.prototype. If you are concerned this will break other functionality on the page then you need to remove it, stringify, then restore it.
function myStringify( o ) {
var temp = Array.prototype.toJSON;
delete Array.prototype.toJSON;
var result = JSON.stringify(o);
Array.prototype.toJSON = temp;
return result;
}

JavaScript array of objects - 0th element undefined but stringify shows objects

I am pulling an object from backbone.js and when I stringify the object I see string literal
'[{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}]'
However, when I assign the non-serialized object to a variable and try to access the 0th element, I get undefined. I would expect to get object
{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}
Is JavaScript not treating
[{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}]
as an indexed array of objects?
To access elements of Backbone.Collection by index, use the Collection#at method:
var first = collection.at(0);
Alternatively, you can use the Collection#first method, which is actually part of the underscore library, but is proxied to Backbone collections for syntactic sugar:
var first = collection.first();
The reason you're seeing the array representation in the serialized JSON is that by convention JSON.stringify looks for a method called toJSON on the object you give to it to stringify, and if one is found, the return value of that method will be used instead. The implementation of Collection#toJSON returns a clone of the collection's internal array of models, and thus the JSON output is an array.
Just tried
var arr = JSON.parse( '[{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}]' );
and
console.log( arr[0] ); // => object
What you've described should work.

Dynamically Reading Array Values form a JSON Object

I am working on a function that accepts a JSON object as a parameter. Each property of the object passed in will be an array. I need to determine the length of each of these arrays.
What I won't know in advance are: the names of the properties, or how many properties there are.
How can I determine the length of each array? Again, I can't refer to any of the properties/keys explicitly because I won't know their names ahead of time. How do I reference each unknown property as an array?
Thank you in advance,
-RS
You can iterate over the object using a for...in loop to access each property.
for (var key in myObject) {
// Check to make sure the property is not part of the `Object` prototype (eg. toString)
if (myObject.hasOwnProperty(key)) {
console.log(key, myObject[key].length);
}
}
In the above example, we iterate over the properties of the object myObject and we log out their length values (assuming they are all arrays).
If by "JSON object" you mean that it is a string of JSON, you can first parse myObject into a true object by using myObject = JSON.parse(myObject) (which works in modern browsers) or myObject = eval("(" + myOjbect + ")") which is considered unsafe (but works in all browsers). After parsing, you may use the above technique to fine array lengths.
Note: Since you updated the post to specify that the object is JSON, you may not need the hasOwnProperty check, but it is safer to always use this test.
Use JSON.parse to convert JSON data to JS Objects, and then you can use Array's length etc properties.
var myObject = JSON.parse(myJSONtext, reviver);
JSON Reference: http://www.json.org/js.html

How do I access the first key of an ‘associative’ array in JavaScript?

I have a js 'associative' array, with
array['serial_number'] = 'value'
serial_number and value are strings.
e.g. array['20910930923'] = '20101102'
I sorted it by value, works fine.
Let's say I get back the object 'sorted';
Now I want to access the first KEY of the 'sorted' array.
How do I do it? I can't think I need an iteration with
for (var i in sorted)
and just stop after ther first one...
thanks
edit: just to clarify, I know that js does not support associative arrays (that's why I put it in high commas in the Title).
2021 Update
Since ES6, properties with string keys are enumerated in insertion order. Here's a nice summary. My original answer from 2010 was correct at the time and is preserved below:
Original answer
JavaScript object properties are specified to have no order, much though many people wish it were different. If you need ordering, abandon any attempt to use an object and use an Array instead, either to store name-value objects:
var nameValues = [
{name: '20910930923', value: '20101102'},
{name: 'foo', value: 'bar'}
];
... or as an ordered list of property names to use with your existing object:
var obj = {
'20910930923': '20101102',
'foo': 'bar'
};
var orderedPropertyNames = ['20910930923', 'foo'];
Try this:
// Some assoc list
var offers = {'x':{..some object...}, 'jjj':{...some other object ...}};
// First element (see attribution below)
return offers[Object.keys(offers)[0]];
// Last element (thanks to discussion on finding last element in associative array :)
return offers[Object.keys(offers)[Object.keys(offers).length - 1]];
Actually JavaScript doesn't support associative arrays, so you can't loop through it in an implied order (e.g. you can't access it via the indexer property array[0] won't access the first element in your object). The syntax is what makes it look like it does, but in reality it doesn't. So you have no "Order" to your objects.
http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
Javascript does not have, and does not
support Associative Arrays. However…
All arrays in Javascript are objects
and Javascript's object syntax gives a
basic emulation of an associative
Array. For this reason the example
code above will actually work. Be
warned that this is not a real array
and it has real pitfals if you try to
use it. The 'person' element in the
example becomes part of the Array
object's properties and methods, just
like .length, .sort(), .splice(), and
all the other built-in properties and
methods.
Just thinking off the top of my head, but could you have another array with the key value pairs swapped?
So the answer would be arrayKeyValueReversed['20101102'] = '20910930923';
When you sort the array, use the first item (array[0]) as the key to get the value in the arrayKeyValueReversed.

Categories