I am facing an issue that JSON.stringify not stringifies all the keys in a JSON Object.
ie. window.performance.getEntries()[0] contains around 17 keys. But on converting to a string, the result contains only 4 keys.
How can I convert all the keys in window.performance.getEntries()[0]?
I want the complete string output of window.performance.getEntries() which is an array and I used JSON.stringify(window.performance.getEntries()).
Thanks in advance..
window.performance seems to have is own toJSON-function and so can determine what will be stringified. Here is a answer and a work around to your question from a similiar question: https://stackoverflow.com/a/20511811/3400898
"If the stringify method sees an object that contains a toJSON method, it calls that method, and stringifies the value returned. This allows an object to determine its own JSON representation."
As other stated it is because there is a toJSON method defined. Basically you need to loop over every index of the array and than every property in the object.
var adjusted = window.performance.getEntries().map( function (result) {
var temp = {}, key;
for (key in result) if (key!=="toJSON") temp[key]=result[key];
return temp;
});
console.log(JSON.stringify(adjusted[0]));
The simplified solution for this problem which I found is
var jsonArray = $.map(performance.getEntries(),function(jsonObj){
var obj = $.extend({},jsonObj);
delete obj.toJSON;
return obj;
});
JSON.stringify(jsonArray);
Related
I wanted to store the object in local storage and I serialized the object using JSON.stringify. Then some of the inner attributes are missing after parse using JSON.parse.
I attached 2 images below to see the changes and appreciate it if anyone can answer a better solution for this. Thanks.
This object is just before stringified using JSON.
This object is stringified and parse using JSON
This is how i store and retreive data
Json.Stringify does not pass functions into the stringified JSON, i.e. functions will not be copied into the string as functions are not valid JSON objects. In your case, the difficulty is a function and as such won't be copied.
You can include the function by using a replacer:
JSON.stringify({
/* your object here */
}, function(key, val) {
return (typeof val === 'function') ? '' + val : val;
});
How can we convert an array of type string back into array.
var arr = '[ "abc", "def"]';
console.log(typeof arr) ==> String
How can i convert it back into an array?
I am getting this array in form of string from an API response. and these are errors which can be multiple. I want to convert them into an array such that i can display them on their correct positions.
If your string is really as shown in your edit (not your original question), it's valid JSON, so you could use JSON.parse:
var str = '["abc", "def"]';
var arr = JSON.parse(str);
Since your array syntax conforms to that of a JSON array: Use a JSON parser.
Browsers have one built-in these days.
arr = JSON.parse(arr);
For a more general approach, you would need to look at eval, but that has numerous drawbacks (including issues of scope, speed, and security).
You can't convert it back, since you don't actually have an array.
an array should be created without the single quotes ... you are creating a string, you want to do something like the following if you want to create an array.
var arr = ["string 1","string 2"];
UPDATE
Since you updated your question, with information regarding why you had a string, you can follow the suggested solution:
JSON.parse(arr);
Use JSON.parse() to convert the JSON string into JSON object.
DEMO
var arr = '[ "abc", "def"]';
console.log(typeof arr); // string
var arr = JSON.parse('[ "abc", "def"]');
console.log(typeof arr); // object
I'm working with a JSON validator that checks a give JSON object against a schema and returns errors if it doesn't match. One of the things I need to do is add missing attributes, but these could potentially be quite deep in the structure. The validator error returns the location of a missing attribute as a string in this format:
'data.thing1.thing2.thingN'
I can strip out the "data." bit easily enough, but I don't know how to translate the rest to correct object notation, in any depth. This is what I've got so far:
var attributeLineage = newField.split(".");
obj[attributeLineage[0]][attributeLineage[1]] = "";
So obviously this only works when there are only two levels of depth. I need to loop through the values in attributeLineage and link them all together to correctly construct the missing attribute in the given object, at any depth. How can this be done?
I might be missing something totally obvious, or going about it the wrong way, but I'm not sure how to proceed.
Using reduce() method get the reference of the inner object and update the property using last element in split array.
var newField = 'data.thing1.thing2.thingN';
// split the string
var attributeLineage = newField.split("."),
// get last element and remove it from splitted array
prop = attributeLineage.pop();
var ob = {
data: {}
};
// get the object reference
var obj = attributeLineage.reduce(function(o, k) {
// return if nested object is defined
// else define and return it
return o[k] || (o[k] = {}) && o[k];
}, ob);
// update the inner object property
obj[prop] = "hi";
console.log(ob);
I have used JSON.stringify() many times and I am aware of some issues such as (described in here):
cycles
too deep objects
too long arrays
However, I am facing incorrect stringify operation on object which is like that:
After running JSON.stringify(obj) on console, I am getting that.
"[{"$$hashKey":"object:103",
"ProductCategories": [{"Id":2,"ShopProductCategoryName":"Drink","isSelected":true}
{"Id":3,"ShopProductCategoryName":"Food","isSelected":true}]
}]"
It only stringifies ProductCategories and $$hashKey which is totally unexpected.
Solving Attempts
If I create new object from obj and stringify it, returns correct JSON.
var newObj = { // Creates new object with same properties.
AllProductCategories: obj.AllProductCategories,
Id: obj.Id,
LabelName: obj.LabelName,
Percentages: obj.Percentages,
ProductCategories: obj.ProductCategories
}
JSON.stringify(newObj); // Returns correct JSON.
I used the code to send object to web api compulsorily, but the way is not what I want, of course.
As I see,
There is no cycles.
It is not too deep. (only has depth 3)
Therefore, I cannot figure out what is wrong.
Well I suggest you create a function that clones your object without $$hashKey property that was set by angular I guess:
function cloneObj (obj) {
var cloned = JSON.parse(JSON.stringify(obj));
delete cloned.$$hashKey;
for(var key in cloned) {
if(typeof cloned[key] === 'object') {
cloned[key] = cloneObj(cloned[key]);
}
}
return cloned;
}
After you clone your object without $$hashKey, then you can stringify it without any problem.
I know this isn't the best way to do it, but I have no other choice :(
I have to access the items in JSONObject by their index. The standard way to access objects is to just wirte this[objectName] or this.objectName. I also found a method to get all the fields inside a json object:
(for (var key in p) {
if (p.hasOwnProperty(key)) {
alert(key + " -> " + p[key]);
}
}
(Soruce : Loop through Json object).
However there is no way of accessing the JSONfields directly by a index. The only way I see right now, is to create an array, with the function above, get the fieldname by index and then get the value by fieldname.
As far as I see it, the p (in our case the JSON file must be an iteratable array to, or else the foreach loop wouldn't work. How can I access this array directly? Or is it some kind of unsorted list?
A JSON Object is more like a key-value-map; so, yes, it is unsorted. The only way to get around is the index->property name map you've already mentioned:
var keysbyindex = Object.keys(object);
for (var i=0; i<keysbyindex.length; i++)
alert(object[keysbyindex[i]]);
But why would you need these indexes? A unsorted map also has no length property, as an Array had. Why don't you use the for-in-loop
var counter = 0; // if you need it
for (var key in object) {
alert(object[key])
counter++;
}
? If you have a parsed JSON object, i.e. a plain JS Object, you won't have to worry about enumerable prototype properties.
Based on Bergis anserwer this is my solution:
var keysbyindex = Object.keys(this);
alert(this[keysbyindex[index]]);
return this[keysbyindex[index] || ""];
However, I think (not tested) it's extremly bad regaring performace and shouldn't be used! But desperate times require desperate measures.....
I don't think you can actually achieve this without creating your own parsing of JSON. You're writing that you want to go trough a JSON-object, but what you're actually trying to do is go trough a plain old Javascript object. Json is simply a string-representation used to transfer/store said object, and in here lies the main problem: the parser that transforms the string into an actual object (ie. the browser in most cases) can chose to ignore the order it finds the properties if it want to. Also, different browsers might have different approaches to parsing JSON for all you know. If they simply use a hash-map for the object that it's simple to loop through it, but the order won't be dependent on the order of the keys in the file, but rather the keys themselves.
For example, if you have the json {"b":"b","a":"a"} and do the for in loop, under some implementations you might end up with a comming first, and in others you might end up with b.
var jsn = {keyName: 'key value result come here...'};
var arr = jsn ? $.map(jsn, function (el) { return el }) : [0];
console.log(arr[0])
$('.result').text(arr[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="result"></span>