What is wrong with this JSON file? - javascript

I put it in a parser and all it gives me is "expecting string on line 19". I have no idea what that means.
{
"name": "Rajeev",
"children": [
{
"name": "Joe",
"children": [
{
"name": "Kevin",
"children": [
{
"name": "George"
}
]
},
{
"name": "John",
"children": [
{
"name": "Barb",
}{
"name": "Michael",
}{
"name": "Charles"
}
]{
"name": "Ravinder"
]
},

Your commas are in the wrong place, e.g.
"children": [
{
"name": "Barb"
},{
"name": "Michael"
},{
"name": "Charles"
}
]

The left one is the right one. see for yourself. you had many extra , and unclosed { and [
http://i.stack.imgur.com/9yKNN.jpg

You have a property / value:
"name": "Barb",
… with a trailing comma so the next thing must be another property / value (the string mentioned in the error message is the property name).
However you have:
}{
Either remove the comma or add more details about Barb.
Then you will need to put a comma between the two objects:
}, {
It seems likely that you intended to place the comma causing teh error between the two objects, so you can just move them.
(You have similar errors throughout the rest of the file)

Sorry for the first answer, I saw a missing comma and automatically assumed that was it, but there were many other errors in there. I think this is what you're trying to do
[
{
"name": "Rajeev",
"children": [
{
"name": "Joe",
"children": [
{
"name": "Kevin",
"children": [
{
"name": "George"
}
]
},
{
"name": "John",
"children": [
{
"name": "Barb"
},
{
"name": "Michael"
},
{
"name": "Charles"
}
]
}
]
}
]
},
{
"name": "Ravinder"
}
]

Related

How to add or update items in this multidimensional JSON?

Let's say we have some houses represented as JSON. Something like this:
[
{
"id": "1",
"code": "1",
"name": "Smith's",
"children": [
{
"id": "",
"code": "11",
"name": "Kitchen",
"children": [
{
"id": "",
"code": "111",
"name": "Sink",
"children": []
}
]
},
{
"id": "",
"code": "12",
"name": "Living Room",
"children": [
{
"id": "",
"code": "121",
"name": "Television",
"children": [
{
"id": "",
"code": "1211",
"name": "Panel buttons",
"children": [
{
"id": "",
"code": "12111",
"name": "Power button",
"children": []
},
{
"id": "",
"code": "12112",
"name": "Colors adjust button",
"children": []
}
]
},
{
"id": "",
"code": "1221",
"name": "Screen",
"children": []
}
]
}
]
}
]
},
{
"id": "2",
"code": "2",
"name": "Taylor's",
"children": [
// Here goes all house places and items like the example above
]
},
{
"id": "1",
"code": "1",
"name": "Wilson's",
"children": [
// Here goes all house places and items like the example above
]
}
]
Take notice that the "code" property, found in each item, is something to represent the "path" until that item, carrying its parents "code" property concatenated with its own position by incremental order. So the code "11" means house 1 and child 1. And 212 would be house 2, child 1, child 2. Also take notice that all items follow the same type. In other words, every item has a children that follows its own type. So, it could be infinite.
Now, I'd like to maintain these structure. Adding items, updating items and so on. Let's say we want to add a carpet in Smith's living room. We would go deep in the structure 2 levels, which are Smith's house (index 0 of the array) and living room (index 1 of the children array). And then add a carpet.
The problem is it won't be 2 levels in all cases. What if I wanted to add a bathroom? It would be level 1, alongside with kitchen in living room (the first children). What if I'd like to add a microwave in the kitchen and add to it buttons, display, etc?
I think I'm a recursive scenario where I have to visit all items and, if it is the one I'm looking to reach at, add/updated it.
I've tried following this example
I couldn't figure it out how to bring it to my case. though.
I appreciate if your contribution is in JavaScript, but feel free to represent it in other language in case you are better in other language =).
There are indeed some questions, like for instance what happens if you have more than 10 items as child and why do you need it?
And what happens if you remove any item on any level? will you recursively start updating all codes?
Nevertheless I gave it a go. In essence what I do in the code is first search for the parent (example: Kitchen) where you want to add it to and then add the new child item (example: Carpet) to it.
The search is a typical recursive search.
The child addition is a typical addition to an array.
For argument's sake I assumed that the fields code always exist and that children is always an array.
// Actual code is underneath the declaration of this array
let houseList = [
{
"id": "1",
"code": "1",
"name": "Smith's",
"children": [
{
"id": "",
"code": "11",
"name": "Kitchen",
"children": [
{
"id": "",
"code": "111",
"name": "Sink",
"children": []
}
]
},
{
"id": "",
"code": "12",
"name": "Living Room",
"children": [
{
"id": "",
"code": "121",
"name": "Television",
"children": [
{
"id": "",
"code": "1211",
"name": "Panel buttons",
"children": [
{
"id": "",
"code": "12111",
"name": "Power button",
"children": []
},
{
"id": "",
"code": "12112",
"name": "Colors adjust button",
"children": []
}
]
},
{
"id": "",
"code": "1221",
"name": "Screen",
"children": []
}
]
}
]
}
]
},
{
"id": "2",
"code": "2",
"name": "Taylor's",
"children": [
// Here goes all house places and items like the example above
]
},
{
"id": "1",
"code": "1",
"name": "Wilson's",
"children": [
// Here goes all house places and items like the example above
]
}
]
addChild(houseList,"11",{name:"Carpet" });
addChild(houseList,"1211",{name: "Volume Up Button"});
addChild(houseList,"1211",{name: "Volume Down Button"});
console.log('new houselist', houseList);
// child is just what you want to add and the parentCode refers to where you want to add it to
function addChild(houseList, parentCode, child) {
let parent = findInHouseList(houseList,parentCode,child);
let amountOfChildren = parent.children.length;
let newCodeName = parentCode +""+ (amountOfChildren+1);
child = {...{id: "", code: newCodeName, children: []}, ...child};
console.log('adding child ', child);
parent.children = [...parent.children, child];
}
function findInHouseList(houseList,code) {
for (let house of houseList) {
let foundElement = findElement(house,code);
if ( foundElement)
return foundElement;
}
}
function findElement(currentElement, code) {
if ( currentElement.code === code)
return currentElement;
if (currentElement.children?.length > 0)
{
for (let child of currentElement.children) {
let foundElement = findElement(child,code);
if ( foundElement)
return foundElement;
}
}
return null;
}
I decided to let the code manage the code names for new children. It seems the easiest.
What you're trying to do is updating a JSON value at a dynamic path.
This function will append a child to the item which holds the specified code.
You may add conditions to check if the item at the code is defined
function appendChild(houses, code, item) {
let path = code.split('')
let o = houses
for (let i = 0; i < path.length; i++) {
let n = path[i] - 1
o = o[n]["children"]
}
o.push(item)
return houses
}
However, you should start your code indexes at 0 and storing them inside the JSON is useless since they are simply the path to reach the item.

How do you delete an empty array from javascript?

For reference I have zero javascript knowledge or any coding knowledge. I typically just hook up applications via IPASS applications that don't require any coding knowledge. However, I found out I need to inject some javascript into the application in order to avoid an error message.
I have the below JSON record.
I need to get rid of the empty array (sorry... if it is not an array but an object? Like I said, no javascript knowledge).
In the below code essentially what I want is to completely delete this line, because there is nothing inside the brackets and it is causing errors:
"lineitemsdata": []
Full JSON record below for reference
"id": "5399286500",
"properties": {
"state": "AB",
"website": null,
"zip": "T3B5Y9"
},
"createdAt": "2021-02-18T22:13:06.111Z",
"updatedAt": "2021-05-17T14:35:09.540Z",
"archived": false,
"associations": {
"deals": {
"results": [
{
"id": "5230410841",
"type": "company_to_deal"
}
]
}
},
"dealdata": [
{
"id": "5230410841",
"properties": {
"hs_lastmodifieddate": "2021-05-13T14:00:33.101Z",
"hs_object_id": "5230410841",
"hubspot_owner_id": "52200226"
},
"associations": {
"line items": {
"results": [
{
"id": "1468189759",
"type": "deal_to_line_item"
},
{
"id": "1468189760",
"type": "deal_to_line_item",
"lineitemsdata": []
}
]
}
}
}
],
"DealOwner": [
{
"id": "52200226",
"email": "email#email.com",
"firstName": "Bob"
}
],
"NetSuiteCustomerID": 1745
}
Item inside object is called a property. If you (for some reason) have to include the property, but don't want it to have any value you can either set it's value to null or undefined.
I suspect I'm going to get criticized for this, but here is a quick and dirty way of removing this specific problem through string replacement. The 'right' way would be to break down your json into separte objects until you get to the level where the offending object lives, remove it, then rebuild it all back. For what it's worth, here's an alternative to that
let json = {
"id": "5399286500",
"properties": {
"state": "AB",
"website": null,
"zip": "T3B5Y9"
},
"createdAt": "2021-02-18T22:13:06.111Z",
"updatedAt": "2021-05-17T14:35:09.540Z",
"archived": false,
"associations": {
"deals": {
"results": [{
"id": "5230410841",
"type": "company_to_deal"
}]
}
},
"dealdata": [{
"id": "5230410841",
"properties": {
"hs_lastmodifieddate": "2021-05-13T14:00:33.101Z",
"hs_object_id": "5230410841",
"hubspot_owner_id": "52200226"
},
"associations": {
"line items": {
"results": [{
"id": "1468189759",
"type": "deal_to_line_item"
},
{
"id": "1468189760",
"type": "deal_to_line_item",
"lineitemsdata": []
}
]
}
}
}],
"DealOwner": [{
"id": "52200226",
"email": "email#email.com",
"firstName": "Bob"
}],
"NetSuiteCustomerID": 1745
}
json = JSON.stringify(json)
let strstart = json.indexOf('"lineitemsdata":[]');
let commapos = json.lastIndexOf(',', strstart);
json = json.substr(0, commapos) + " " + json.substr(commapos + 1);
json = json.replace('"lineitemsdata":[]', '');
json = JSON.parse(json)
console.log(json)
You can use this to strip any empty lineitems arrays from your json.
Assuming the reference to your record is json
for(dealIdx in json.dealdata) {
for (resultIdx in json.dealdata[dealIdx].associations["line items"].results) {
let lineItemsData = json.dealdata[dealIdx].associations["line items"].results[resultIdx].lineitemsdata
if (lineItemsData != undefined && lineItemsData.length === 0 ) {
delete json.dealdata[dealIdx].associations["line items"].results[resultIdx].lineitemsdata
}
}
}

Concatenating child array to parent

Right now I have an array of object with children that also have an array of objects.
[
{
"code": "mock-code",
"name": "mock-name",
"children": [
{
"code": "mock-child-code",
"name": "mock-child-name",
},
{
"code": "mock-child-code",
"name": "mock-child-name",
},
],
},
{
"code": "mock-code",
"name": "mock-name",
"children": [],
},
{
"code": "mock-code",
"name": "mock-name",
"children": [
{
"code": "mock-code",
"name": "mock-name",
}
],
}
]
I want to extract the children array and concat them to the parent array like below.
[
{
"code": "m1",
"name": "mock-name",
"children": [
{
"code": "mc-1",
"name": "mn-1",
},
{
"code": "mc-2",
"name": "mn-2",
},
],
},
{
"code": "m2",
"name": "mock-name",
"children": [],
},
{
"code": "mm3",
"name": "mock-name",
"children": [
{
"code": "mc-3",
"name": "mn-3",
}
],
}
{
"code": "mc-1",
"name": "mn-1",
},
{
"code": "mc-2",
"name": "mn-2",
},
{
"code": "mc-3",
"name": "mn-3",
}
]
What are someways to do this. I'm currently looping though the child array creating a new array checking if it's not empty. It all seems a bit messy. Is there a clean way to do this?
let fullList = New Array()
parentData.forEach(element => {
if (!!element.children.length) {
fullList.push(element.children);
}
});
return parentData.concat(fullList);
This isn't giving me the desired results since it's adding another array to the parent object but this is where I am at.
const newArray = originalArray.flatMap(element => [element, ...element.children])
This should do it, and as a bonus will preserve the order (parent1, parent1's children, parent2, parent2's children etc.)
Of course, this works if you have only one level of nesting. If you have greater depth level, that would be a bit more complex, probably using Array.prototype.reduce().

How can I get to the last level of a json nest and format the output dynamically?

I have this json:
[
{
"name": "MARVEL",
"superheroes": "yes"
},
{
"name": "Big Bang Theroy",
"superheroes": "NO",
"children": [
{
"name": "Sheldon",
"superheroes": "NO"
}
]
},
{
"name": "dragon ball",
"superheroes": "YES",
"children": [
{
"name": "goku",
"superheroes": "yes",
"children": [
{
"name": "gohan",
"superheroes": "YES"
}
]
}
]
}
]
I know how to loop and go through it but I need an output like this:
[
{
"name": "MARVEL",
"answer": [
{
"there_are_superheroes": "YES"
}
]
},
{
"name": "Big Bang Theroy",
"answer": [
{
"there_are_superheroes": "NO",
"new_leaft": [
{
"name": "sheldon",
"there_are_superheroes": "NO"
}
]
}
]
},
{
"name": "dragon ball",
"answer": [
{
"there_are_superheroes": "YES",
"new_leaft": [
{
"name": "goku",
"answer": [
{
"there_are_superheroes": "YES",
"new_leaft": [
{
"name": "gohan",
"answer": [
{
"there_are_superheroes": "YES"
}
]
}
]
}
]
}
]
}
]
}
]
I tried something like this:
format(d) {
if (d.children) {
d.children.forEach((d) => {
format;
});
}
}
format(data);
I don't know how to get the structure I want. I have tried to do it with foreach, but at one point I don't know how to dynamically access until the last children, this is an example but I can have n levels where there can be elements with more children. In my real project I am getting a structure from a web service, I need to structure it like this.
the attribute called superheroes I want it to be shown inside an array called answer and inside of it, there_are_superheroes it will have its value.
"name": "MARVEL",
"answer": [
{
"there_are_superheroes": "YES", --> `there_are_superheroes` was `superheroes`,
"new_leaft": [
{
.
.
and new_leaft is the equivalent of children
As I said, I know how to go through objects and arrays but in this case, I don't know how to go to the last children nested of each object.
This is how to do one level of recursion:
function format(l){
const result = {name: l.name};
result.answer = [{there_are_superheroes: l.superheroes}];
result.answer[0].new_leaft = l.children;
return result;
}
format({
"name": "Big Bang Theroy",
"superheroes": "NO",
"children": [
{
"name": "Sheldon",
"superheroes": "NO"
}
]
})
// result:
{
"name": "Big Bang Theroy",
"answer": [
{
"there_are_superheroes": "NO",
"new_leaft": [
{
"name": "Sheldon",
"superheroes": "NO"
}
]
}
]
}
If the list of possible keys is fixed, it's very simple. Otherwise use Object.assign to copy all the keys (or just iterate through those), then modify the necessary keys.
Now you have to figure out where to put the recursion calls (hint: l.children.map(format), whether the key should be named tree or new_leaf(t), check if the field exists and handle accordingly, (See the question In Javascript. how can I tell if a field exists inside an object? - Stack Overflow), etc.

Add key values dynamically to nested object in Javascript

This might be a duplicate of this but did not get proper solution over there. I have object as below,
var replyDataObj = {
"department": {
"name": getCache("departmentName")
},
"subject": replyEmailSubject,
"payload": {
"email": {
"contents": {
"content": [
{
"type": "html",
"value": replyEmailContent
}
]
},
"emailAddresses": {
"from": fromEmailId,
"to": {
"address": [
toEmailId
]
}
}
}
}
}
I want to add following key values to 'emailAddresses' key dynamically depending upon whether cc field is present or not,
"cc": {
"address": [
ccEmailId
]
}
So it will look like,
var replyDataObj = {
"department": {
"name": getCache("departmentName")
},
"subject": replyEmailSubject,
"payload": {
"email": {
"contents": {
"content": [
{
"type": "html",
"value": replyEmailContent
}
]
},
"emailAddresses": {
"from": fromEmailId,
"to": {
"address": [
toEmailId
],
"cc": {
"address": [
ccEmailId
]
}
}
}
}
}
}
I tried to add this using object[key] as below, object.key but no luck
replyDataObj[payload][emailAddresses][cc]={
"address": [
ccEmailId
]
}
I tried multiple ways and searched a lot but did not get the solution. Any help in this regard will be greatly appreciated. Thank you.
Put strings inside []:
replyDataObj['payload']['emailAddresses']['cc']={
"address": [
ccEmailId
]
}
As answered by #K.Kirsz, I was missing strings inside [] (quotes). Also added missing 'email' key to solve my issue.
replyDataObj['payload']['email']['emailAddresses']['cc']={
"address": [
ccEmailId
]
}

Categories