I have JSON getting returned as:
[
{
"node" : "GMC",
"node1" : "2500",
"node2" : [ {
"node2" : "GMC 2500",
"location" : "Lot",
}]
}
]
I want to parse this out and put in a UL, however, I get an error such as
[ objects are not valid as reach child (found: object with keys { node, node1 })
I'm trying to read it such as
{types.map(data => {
<li> {data.node} // this displays GMC
<ul> { data.node1 } </ul> //get the error.
<ul> { data.node1.node1 } </ul> //also gives same error)
}
I need to show it as:
GMC
2500
Lot
is there another way to parse out this JSON file?
use =>() to return .
data.node1.node1 is undefined because node1 is not an object it's a string so it does not have propreties
li should be an ul child not the inverse.
return an array of li:
<ul>
types.map(data =>
([
<li>{data.node}</li>,
<li>{data.node1}</li>,
])
</ul>
5.(bonnus) types is not a valid JSON but it does not matter here you can check if your JSON is valid here
There are a few issues with your code (ul should contains li, not the opposite. Also data.node1.node1 doesn't exist). But you can try something like:
See on JS Fiddle
render() {
const types = [
{
"node" : "GMC",
"node1" : "2500",
"node2" : [
{ "node2" : "GMC 2500", "location" : "Lot" }
]
}
]
return (
<div>
<ul>
{
types.flatMap(data => ([
<li>{data.node}</li>,
<li>{data.node1}</li>,
data.node2.map(node2 => ([
<li>{node2.node2}</li>,
<li>{node2.location}</li>,
]))
]))
}
</ul>
</div>
)
}
}
Related
I am trying to traverse a tree and create a Map data structure that holds only the first parent of the elements . key{child element} : value {array of 1st parents}
My code
global.parentMap = new Map()
function readTree(root) {
let queue = [root];
while (queue.length > 0) {
let node = queue.shift();
for (let childType in node.children) {
for (let child of node.children[childType]) {
let newChild = {...child};
queue.push(newChild);
if(global.parentMap.has(newChild.item.name)){
global.parentMap.set(newChild.item.name,global.parentMap.get(newChild.item.name).push(node.item.name))}
if(!parentMap.has(newChild)){
global.parentMap.set(newChild.item.name,[]);
}
console.log("Parent"+node.item.name+" has childs "+newChild.item.name)
global.parentMap.get(newChild.item.name).push(node.item.name);
}
}
}
}
The issue is that the new global does not push parents as a value to the Map data structure and it is always overridden
Console output
Parent : testing_group has childs:command_name
Parent : agv_commands has childs:location_name
Parent : agv_commands has childs:header_frame_id
Parent : agv_commands has childs:location_coordinates
Parent : agv_commands has childs:robot_name
Parent : agv_commands has childs:load_id
Parent : agv_commands has childs:command_item
Parent : agv_commands has childs:command_name
Map(7) {
'command_name' => [ 'agv_commands' ], // it should include testing_group
'location_name' => [ 'agv_commands' ],
'header_frame_id' => [ 'agv_commands' ],
'location_coordinates' => [ 'agv_commands' ],
'robot_name' => [ 'agv_commands' ],
'load_id' => [ 'agv_commands' ],
'command_item' => [ 'agv_commands' ]
}
There are these issues:
The following code defines a Map entry as an integer, not an Array:
global.parentMap.set(newChild.item.name, global.parentMap.get(newChild.item.name).push(node.item.name))
...because push does not return an array, it first mutates the array, but then returns an integer (the length of the array), which you then set as Map value.
This code should just be removed, as a few statements further down, it is done correctly with:
global.parentMap.get(newChild.item.name).push(node.item.name);
parentMap is here accessed without the global. prefix, which is not really a problem, but is inconsistent with the rest of the code:
if(!parentMap.has(newChild))
In the same expression, the has method is getting an object as argument, while your Map is keyed by strings. So change it to:
if(!global.parentMap.has(newChild.item.name))
With those fixes it should work.
I have some documents which are organized in a model tree structure (depth is variable!). Unfortunately some documents are missing and I need to find those broken chains. As you can see the last document in that chain has always the target field. This is the starting point and I have to look upwards using parent. The last element in that chain has always the field type.
{
"_id" : "K7NSxNEnNSr9nCszR",
"title" : "title",
"type" : "book",
"ancestors" : [ ]
}
{
"_id" : "diyvwYz66yoTCTt9L",
"field" : "something",
"parent" : "K7NSxNEnNSr9nCszR",
"ancestors" : [
"K7NSxNEnNSr9nCszR"
]
}
{
"_id" : "diyvwYz66yoTCTt9L",
"field" : "anything",
"target" : "D2YuXtM6Gzt4eWaW2",
"parent" : "QWvdAyftSGANM3zy8",
"ancestors" : [
"K7NSxNEnNSr9nCszR",
"QWvdAyftSGANM3zy8"
]
}
What I need to know is if any parent is missing or if the last element (=type existing) is missing.
var broken = [];
Collection.find({ target: { $exists: true }}).forEach(function(element) {
var startDocID = element._id;
if (Collection.find({ _id: element.parent }).count() === 0)
broken.push(startDocID);
});
console.log(broken);
But this isn't working well as I need to use a loop to get upwards until the top document (= type existing).
You're talking about recursion here if you need to go down the tree, so you probably need to write a recursive search function
var broken = [];
Collection.find({ target: { $exists: true }}).forEach(function(element) {
function recurse(e) {
var startDocID = e._id;
var nodes = Collection.find({ _id: e.parent });
if (node.count() === 0)
{broken.push(startDocID);}
else {
nodes.fetch().forEach(node) {
recurse(node)
}
}
recurse(element);
}
});
or something of that sort... (hard to debug without the data)
I'm trying to delete a subdocument in mongoDb but can't succeed in it. I've tried with $update,$push and $pull but I'm not successful.
I have the following document:
db.users.findOne({"_id": ObjectId("545677a9e4b0e0ef9379993c")})
{
"_class" : "com.xxx.xxx.server.da.User",
"_id" : ObjectId("545677a9e4b0e0ef9379993c"),
"bookSummaries" : [
{
"_id" : ObjectId("545677e7e4b0e0ef9379993d"),
"isbn" : "2746969644"
"title": "test title"
},
{
"_id" : ObjectId("546a522a44ae4f5e652fdca7"),
"loanSummaries" : [
{
"loanStatus" : "REQUESTED",
"loanId" : "5473992044aec466a619290c"
},
{
"loanStatus" : "REQUESTED",
"loanId" : "5473997d44aec466a619290d"
},
{
"loanStatus" : "REQUESTED",
"loanId" : "547605a744ae0f0d558ae757"
}
],
"testArray" : [
{
"title" : "Back to the future",
"id" : "test"
},
{
"title" : "Back to the future",
"id" : "test2"
},
{
"title" : "Back to the future",
"id" : "test3"
},
"test ",
"test ",
"test 2",
"test 2",
{
"loanStatus" : "REQUESTED"
}
],
"title" : "Back to the future"
}
]
}
and I'm trying to create the queries to:
delete the whole "testArray" subdocument for only this specific subdocument
delete a specific loanSummaries give its loanId for this specific subdocument
Can you help me creating those queries? I've seen several post like this one, but it is not the same problem.
Thanks a lot
I recently had the same problem where I had to remove a nested subarray. In the query you need to identify the exact object that you want to remove, and then in your update query you can use the $ sign as index for the object in the array that you want to pull.
var query = {
"_id" : ObjectId(someUserId),
"bookSummaries._id" : ObjectId(bookId), //might also work with isbn as long as it is uniq
"bookSummaries.loanSummaries.loanId" : loanId
};
var updateQuery = {
"$pull" : {
"bookSummaries.$.loanSummaries" : {
"loanId": loadId
}
}
}
Update
I tried the following queries in my shell which worked fine. You will have to enter the appropirate ids.
var query = { "_id" : ObjectId("53b73b1108fe927c0e00007f"), "bookSummaries._id" : ObjectId("53b73b1108fe927c0e00007f"), "bookSummaries.loanSummaries.loanId" : "53b73b1108fe927c0e00007f" }
var updateQuery = { "$pull" : { "bookSummaries.$.loanSummaries" : { "loanId": "53b73b1108fe927c0e00007f" } } }
Update 2
If you already know the index of item/object you want to remove you can use the queries below in order to achieve this.
Find the document you want to edit
var query = {
"_id" : ObjectId(someUserId),
};
Unset the object you want to remove
var update1 = {
"$unset" : {
"bookSummaries.1.loanSummaries.2" : 1
}
}
Pull the object which has the value null.
var update2 = {
"$pull" : {
"bookSummaries.1.loanSummaries" : null
}
}
And to remove you can basically use the same queries.
Find the document you want to edit
var query = {
"_id" : ObjectId(someUserId),
};
Unset the object you want to remove
var update1 = {
"$unset" : {
"bookSummaries.0.testArray" : 1
}
}
Because MongoDB provides a full JavaScript environment you can easily manipulate the document and save the data back to the db.
*Note: if you are using MongoDB with php or python etc. there are equivalent ways to do that.
1.to delete whole "testArray" subdocument for only this specific subdocument for example index(1) do
db.users.find({"_id": ObjectId("545677a9e4b0e0ef9379993c")}).forEach(function (user) {
delete user.bookSummaries[1].testArray;
//Saveing the changes
db.users.save(user);
});
to delete a specific loanSummaries give its loanId for this specific subdocument for example id 5473992044aec466a619290c do
db.users.find({"_id": ObjectId("545677a9e4b0e0ef9379993c")}).forEach(function (user) {
var loanToDelete = "5473992044aec466a619290c";
var loanIndexToDelete = -1;
var i;
for(i in user.bookSummaries[1].loanSummaries) {
if(user.bookSummaries[1].loanSummaries[i].loanId === loanToDelete) {
loanIndexToDelete = i;
break;
}
}
if (loanIndexToDelete > -1) {
delete user.bookSummaries[1].loanSummaries[loanIndexToDelete];
}
//Saving the changes
db.users.save(users);
});
I had to do something similar but delete multiple subdocuments instead of just one. My query included an array of ids and this worked for me:
User.updateOne(
{ _id: userId },
{
$pull: { bookSummaries: { _id: { $in: ids } } },
});
I have one tree-like structure containing block with certain id. Then I have another object, that contains 'id' : objectPart pairs.
Tree:
var tree = [
{
'property' : 'value',
'id' : 'someID',
//more properties...,
'content' : [
{
'prop' : 'something',
...
}
]
},
{
'prop' : 'val',
...
'content' : []
}
]
ID index:
{
'someID' : tree[0]
}
I need some way how when I do delete ID_index.someID, that object gets also deleted from main structure.
Structure after this code should look like this:
[
{
'prop' : 'val',
...
'content' : []
}
]
Instead of using delete you can write your own remove function. It should look like this:
function myRemove(stringId) {
delete ID_index[stringId]; //remove property from ID_index
objIndex = ... //find object index in tree array
tree.splice(objIndex, 1); //remove object from tree array
}
I have a JSON string that looks like this:
{
"resultType" : "history",
"currentTime" : "2011-10-22T15:46:00+00:00",
"columns" : ["date","orders","quantity","low","high","average"],
"rowsets" : [
{
"generatedAt" : "2011-10-22T15:42:00+00:00",
"rows" : [
["2011-12-03T00:00:00+00:00",40,40,1999,499999.99,35223.50],
["2011-12-02T00:00:00+00:00",83,252,9999,11550,11550]
]
}
]
}
Every time I try to parse it, I use code like this:
var data = JSON.parse(json);
console.log(data);
And the following is what is printed to the console:
{
"resultType" : "history",
"currentTime" : "2011-10-22T15:46:00+00:00",
"columns" : ["date","orders","quantity","low","high","average"],
"rowsets" : [
{
"generatedAt" : "2011-10-22T15:42:00+00:00",
"rows" : [Object]
}
]
}
I've tried a couple of things, but how can I get the data in the rows field? After parsing, the console just shows [Object].
The output you're seeing is just the way it's being displayed. If you access data.rowsets[0].rows, you can see that the JSON was indeed successfully parsed. You can also use util.inspect() when specifying the depth property to tell Node.js to recurse deeper when formatting the object.
Here is an example using util.inspect():
var data = JSON.parse(json);
// a null depth means to recurse indefinitely
console.log(util.inspect(data, { depth: null }));
Have tested your code. It's fine.
var a = {
"resultType" : "history",
"currentTime" : "2011-10-22T15:46:00+00:00",
"columns" : ["date","orders","quantity","low","high","average"],
"rowsets" : [
{
"generatedAt" : "2011-10-22T15:42:00+00:00",
"rows" : [
["2011-12-03T00:00:00+00:00",40,40,1999,499999.99,35223.50],
["2011-12-02T00:00:00+00:00",83,252,9999,11550,11550]
]
}
]
}
var util = require('util');
console.log(util.inspect(a.rowsets[0].rows, { showHidden: true, depth: null }));