I think your data array should be like this:
var data = [{
name: string,
active: bool,
data: { //Use {} instead of []
value: number,
date: string
}
}]
Answer from hamed on Stack OverflowI think your data array should be like this:
var data = [{
name: string,
active: bool,
data: { //Use {} instead of []
value: number,
date: string
}
}]
You can actually use the second argument to JSON.stringify. Two options for this, you can either specify all the prop names you want stringified:
var data = [{
name: string,
active: bool,
data: [
{value: number},
{date: string}
]
}]
JSON.stringify(data, ['name', 'active', 'data', 'value', 'date'])
=> '[{
"name":"string",
"active":"bool",
"data":[
{"value":"number"},
{"date":"string"}
]}
]'
Or use a replacer function with the same result:
JSON.stringify(data, function replacer(key, value) { return value})
=> '[{
"name":"string",
"active":"bool",
"data":[
{"value":"number"},
{"date":"string"}
]}
]'
Original source: https://javascript.info/json
json - Javascript Stringify Nested Objects with Loop References - Code Review Stack Exchange
ajax - JSON.stringify() - nested objects - Stack Overflow
Stringying this JSON drops all elements of the nested array
ajax - JSON stringify nested object - Stack Overflow
The answer I was looking for was: You need to use JSON.stringify to first serialize your object to JSON, and then specify the content-type so your server understands it's JSON.
So, contentType and stringify are necessary if the server is expecting JSON.
If this is jQuery (it looks like it is), the data parameter accepts an object and performs the necessary serialization to pass it as an associative array to the server. You don't stringify if before passing it.
Hello all, this is my first ever reddit post so please bare with me.
I am having an issue when trying to stringify a json that contains an array of jsons.
Here is the code:
function addImages(imageArr, values){
//Declare an empty array of images
var images = []
//For each image object in the image array
for(var image of imageArr){
//Create a new file reader
const reader = new FileReader();
//Read the base64 data from the image
reader.readAsDataURL(image);
reader.onload = function () {
//Creat a json with the name of the image and the
//base64 data of the image
var imageJSON = {
"name" : image.name,
"content" : reader.result
}
//Push that json to the image array
images.push(imageJSON);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
//create a json to hold the entire list of images
const imageListJSON = {
//When i stringify the array, the result is always "[]"
"images" : JSON.stringify(images)
}
//merge this image list with values, a json containing user data
const userData = {...values, ...imageListJSON};
return userData;}
(For context, the imageArr parameter is an array of Web API file objects that are all of either png, jpg, or jpeg images)
The issue is, when i post this data to my backend, all the elements of the image array are dropped. I discovered this was because under the hood, they are stringified and nested objects cant be stringified. I have tried in numerous ways to solve this:
-
Stringify the imageJSON before pushing it to the images array (this correctly stringifies the jsons in the array)
-
Stringify the images array when I put it in the imageListJSON (you can see this in my code, the resulting string is always "[]")
-
Stringify the entire imageListJSON before merging it with values into userData (the resulting string is something like "/"images/" : /"[]/"")
-
Every permutation of the previous items.
If anyone can help me out with this, it'd be greatly appreciated. If you need more context, let me know and I will give it to you. I wanted to upload some images of the output but it isn't letting me upload images for some reason.
Thanks
EDIT: Figured I would add this as well, I thought it might be because the reader function is asynchronous and maybe the data wasn't being put into the array at all before it was being stringified, but if I just console.log the array by itself before returning, the array is correctly populated with the image data. It is only when i stringify it that all the elements get dropped.
You're over-complicating it. Don't stringify until the very end, otherwise you will end up with json inside of json, which is unlikely to be useful in any situation.
var address = {
country: $('#country').val(),
region: $('#description').val(),
postalCode: $('#postalCode').val(),
locality: $('#locality').val(),
additionalInfo: $('#additionalInfo').val()
};
var data = {
agencyName: $('#agencyName').val(),
description: $('#description').val(),
phoneNumber: $('#phoneNumber').val(),
webSite: $('#webSite').val(),
address: address
};
$.ajax({
type: "post",
url: "registerAgency",
data: JSON.stringify(data),
contentType: "application/json",
success: function(responseData, textStatus, jqXHR) {
alert("data saved")
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
the address member on object data is already stringified. The subsequent call will treat this as a string value (which it is!) JSON.stringify() will handle nested objects fine.
If you're willing to go to the effort of whitelisting, then you can establish an array of valid keys, which can provide the ability to nest similar to how many systems do JSON nesting (a . separator, or any separator of your choosing).
var whitelistedObj = whitelistJson(obj, ["company_name", "example", "address.street", "address.example"]);
function whitelistJson(obj, whitelist, separator) {
var object = {};
for (var i = 0, length = whitelist.length; i < length; ++i) {
var k = 0,
names = whitelist[i].split(separator || '.'),
value = obj,
name,
count = names.length - 1,
ref = object,
exists = true;
// fill in any empty objects from first name to end without
// picking up neighboring fields
while (k < count) { // walks to n - 1
name = names[k++];
value = value[name];
if (typeof value !== 'undefined') {
if (typeof object[name] === 'undefined') {
ref[name] = {};
}
ref = ref[name];
}
else {
exists = false;
break;
}
}
if (exists) {
ref[names[count]] = value[names[count]];
}
}
return object;
}
I have a JSFiddle showing its usage as well (to ensure it actually worked on my admittedly small sample set).
You can add toJSON method in your huge JSON objects:
var test = {
"company_name": "Foobar",
"example": "HelloWorld",
"address": {
"street": "My Street 12",
"example": "BarFoo",
"details": "Berlin",
},
toJSON: function () {
return {
company_name: this.company_name,
address: {
street: this.address.street,
example: this.address.example
}
}
}
}
And, you get:
console.log(JSON.stringify(test)); // "{"company_name":"Foobar","address":{"street":"My Street 12","example":"BarFoo"}}"
Or, you can use some filter function: (this function using lodash)
function filter(object, keys, sep) {
sep = sep || '.';
var result = {};
_.each(keys, function (key) {
var keyParts = key.split(sep),
res = object,
branch = {},
branchPart = branch;
for (var i = 0; i < keyParts.length; i++) {
key = keyParts[i];
if (!_.has(res, key)) {
return;
}
branchPart[key] = _.isObject(res[key]) ? {} : res[key];
branchPart = branchPart[key];
res = res[key];
}
_.merge(result, branch);
});
return result;
}
console.log(JSON.stringify(filter(test, ['company_name', 'address.street', 'address.example']))); // "{"company_name":"Foobar","address":{"street":"My Street 12","example":"BarFoo"}}"
Check out jsfiddle http://jsfiddle.net/SaKhG/
I'm trying JSON.parse but getting errors.
JSON.parse({ users: '{"id":"ckmxexkj4eg6b0b63"}' })