I am trying to iterate over and retrieve some data from JSON file using D3 Javascript.
Here is the JSON file:
{
"Resources":
[
{
"subject": "Node 1",
"group" : "1"
},
{
"predicate": "Node 2",
"group" : "2"
},
{
"object": "Node 3",
"group" : "3"
},
{
"subject": "Node 4",
"group" : "4"
},
{
"predicate": "Node 5",
"group" : "5"
},
{
"object": "Node 6",
"group" : "6"
}
]
}
This is my code in D3 Javascript for iterating and retrieving data:
d3.json("folder/sample.json", function(error, graph) {
document.write(graph.Resources[0].subject);
// The code for retrieving all the elements from the JSON file
});
The code above retrieves the first subject which is: Node 1. I could not even retrieve the group.
Could anyone please help me iterate over the JSON file Resources and retrieve the elements: subject, predicate, object and group, using any sort of iterations such as a for loop.
The group lines in your JSON file should look like "group" : "2". Also, your JSON contains a single object (Resources); that's why your document.write is only called once. You'll need to iterate through the value of Resources:
d3.json("test.json", function(error, graph) {
var resources = graph.Resources;
for (var i = 0; i < resources.length; i++) {
var obj = resources[i]
for (var key in obj) {
console.log(key+"="+obj[key]);
}
}
});
will get you
subject=Node 1
group=1
...
I'd like to summarize what I've already wrote in several question's comments.
Because posted JSON file was invalid it was not possible to iterate over it. Original JSON file:
{
"Resources":
[
{
"subject": "Node 1",
"group" = "1"
},
...
{
"object": "Node 6",
"group" = "6"
}
]
}
Each line which contains property group = "x" is wrong. It should be group : "x".
Those kind of errors/typos are easily overlooked. They can be find out checking JSON file with proper tool like JSON validator. In this case JSONLint tool reported:
Parse error on line 5:
... "group"="1" } ]
----------------------^
Expecting '}', ':', ',', ']'
After fixing format of file, iteration could be done easily using any loop: variable graph contains object Resources, which is an array of objects. Each of them contains common property group.
Related
I am using json-server as my fake API data. I am implementing the search functionality to it. I created an endpoint like this -
getData : ( searchTerm : string ) => axios.get(`http://localhost:3000/books?=${searchTerm}`).then((response) => setData(response));
and I am utilizing into my input field to get the searched results.
Let's say My json object coming back from the Json-server is as follows -
[
{
"Id": 1,
"name" : "car"
},
{
"Id": 2,
"name" : "bike"
},
{
"Id": 3,
"name" : "ninja bike"
}]
now, the problem is , when I search for "car", it gives me the json result.
but, when I search for "brand new car", it should give me the "car's" object at least, as word "car" is a match. but it is giving me [], empty array.
So please suggest me how could i look for specific words into my json-server's data?
so that whenever , the end user even make a vague unstructured search, it should look for specific words like "car", in this case and return that car object.
You can make a simple filter to check if your string is in there
let json = [{
"Id": 1,
"name": "car"
},
{
"Id": 2,
"name": "bike"
},
{
"Id": 3,
"name": "ninja bike"
}
]
let searchString = "brand new car".split(" ") // ["brand", "new", "car"]
let filter = json.filter(json => searchString.includes(json.name))
if (filter.length) {
console.log(filter[0].name)
console.log(filter[0].Id)
}
else console.log("not found")
I have a document structure something along the lines of the following:
{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
{
"name" : "name1",
"someNestedArray" : [
{
"name" : "value"
},
{
"name" : "delete me"
}
]
}
]
}
I want to delete the nested array element with the value "delete me".
I know I can find documents which match this description using nested $elemMatch expressions. What is the query syntax for removing the element in question?
To delete the item in question you're actually going to use an update. More specifically you're going to do an update with the $pull command which will remove the item from the array.
db.temp.update(
{ _id : "777" },
{$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}}
)
There's a little bit of "magic" happening here. Using .0 indicates that we know that we are modifying the 0th item of someArray. Using {"name":"delete me"} indicates that we know the exact data that we plan to remove.
This process works just fine if you load the data into a client and then perform the update. This process works less well if you want to do "generic" queries that perform these operations.
I think it's easiest to simply recognize that updating arrays of sub-documents generally requires that you have the original in memory at some point.
In response to the first comment below, you can probably help your situation by changing the data structure a little
"someObjects" : {
"name1": {
"someNestedArray" : [
{
"name" : "value"
},
{
"name" : "delete me"
}
]
}
}
Now you can do {$pull : { "someObjects.name1.someNestedArray" : ...
Here's the problem with your structure. MongoDB does not have very good support for manipulating "sub-arrays". Your structure has an array of objects and those objects contain arrays of more objects.
If you have the following structure, you are going to have a difficult time using things like $pull:
array [
{ subarray : array [] },
{ subarray : array [] },
]
If your structure looks like that and you want to update subarray you have two options:
Change your structure so that you can leverage $pull.
Don't use $pull. Load the entire object into a client and use findAndModify.
MongoDB 3.6 added $[] operator that facilitates updates to arrays that contain embedded documents. So the problem can be solved by:
db.test.update(
{ _id : "777" },
{$pull : {"someArray.$[].someNestedArray" : {"name":"delete me"}}}
)
As #Melkor has commented (should probably be an answer as itself),
If you do not know the index use:
{
_id: TheMainID,
"theArray._id": TheArrayID
},
{
$pull: {
"theArray.$.theNestedArray": {
_id: theNestedArrayID
}
}
}
From MongoDB 3.6 on you can use arrayFilters to do this:
db.test.update(
{ _id: "777" },
{ $pull: { "someArray.$[elem].someNestedArray": { name: "delete me" } } },
{ arrayFilters: [{ "elem.name": "name1"}] }
)
see also https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/index.html#update-all-documents-that-match-arrayfilters-in-an-array
Other example and usage could be like this:
{
"company": {
"location": {
"postalCode": "12345",
"Address": "Address1",
"city": "Frankfurt",
"state": "Hessen",
"country": "Germany"
},
"establishmentDate": "2019-04-29T14:12:37.206Z",
"companyId": "1",
"ceo": "XYZ"
},
"items": [{
"name": "itemA",
"unit": "kg",
"price": "10"
},
{
"name": "itemB",
"unit": "ltr",
"price": "20"
}
]
}
DELETE : Mongodb Query to delete ItemB:
db.getCollection('test').update(
{"company.companyId":"1","company.location.city":"Frankfurt"},
{$pull : {"items" : {"name":"itemB"}}}
)
FIND: Find query for itemB:
db.getCollection('test').find(
{"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
{ "items.$": 1 }
)
3.UPDATE : update query for itemB:
db.getCollection('test').update
(
{"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
{ $set: { "items.$[].price" : 90 }},
{ multi: true });
Using node.js(javascript) how do I access the GetDataResult node in this JSON data that has been converted from SOAP data.
{
"s:Envelope": {
"$": {
"xmlns:s": "http://schemas.xmlsoap.org/soap/envelope/"
},
"s:Body": [{
"GetDataResponse": [{
"$": {
"xmlns": "http://tempuri.org/"
},
"GetDataResult": ["You entered: TEST"]
}]
}]
}
}
Test using nodejs interactive mode :
$ node
> var x = {
... "s:Envelope": {
..... "$": {
....... "xmlns:s": "http://schemas.xmlsoap.org/soap/envelope/"
....... },
..... "s:Body": [{
....... "GetDataResponse": [{
......... "$": {
........... "xmlns": "http://tempuri.org/"
........... },
......... "GetDataResult": ["You entered: TEST"]
......... }]
....... }]
..... }
... }
undefined
> console.log(x["s:Envelope"]["s:Body"][0]["GetDataResponse"][0]["GetDataResult"][0])
Output :
'You entered: TEST'
Explanations :
I try to elaborate a bit from comments below. There is no container, I try to explain :
You have to think json like what it is : an object or a data structure.
In python, we would say it's a dict, in perl a hash table etc... Globally, it's all about associative array
So when you see in JSON :
"key" : { "value" }
it's an associative array
If instead you see
"key": [
{ "key1": "foo" },
{ "key2": "bar" },
{ "key3": "base" }
]
It's an array of hashes or array of associative arrays.
When you access a simple associative array without spaces or odd characters, you can (in js do :
variable.key
In your case, you have odd character : in the key name, so x.s:Envelope wouldn't work. Instead we write: x['s:Envelope'].
And as far as you have arrays of associative arrays inside [], you have to tell js which array number you need to fetch. It's arrays with only one associative array, so it's simple, we go deeper in the data structure by passing array number, that's what we've done with
x['s:Envelope']["s:Body"][0]
^
|
I'm sending a JSON array to a script for further processing. The JSON array contains a bunch of objects each of which contain a further array of objects. What I need to know is how to access values within those nested objects. So, for instance, if the script receives the following:
petlist = [
{"cats":[
{"catName":"Felix","catType":"British short haired"}
]
},
{"dogs":[
{"dogName":"Fido","dogType":"Labrador"}
]
},
{"fish":[
{"fishName":"Bob","fishType":"Goldfish"}
]
},
{"birds":[
{"birdName":"Polly","birdType":"Parrot"}
]
}
]
How would I then address, say, a) dogName, b) birdType, or c) the entire cats object?
Also, am I correct in my terminology here? As I understand it the stuff in square brackets is an array, while the stuff in curly braces is an object.
edit: I am building the JSON in Javascript and I then need to access the elements in a Jade template (in an 'each' loop)
Thanks
I changed your JSON a little bit because I think it was not very fun to work with. Basically I just loop through the objects thats why I thought you should have a key like name instead of dogName, catName and so on.
You can find the working example with Jade in this JSFiddle
HTML
<div id="jadeoutput"></div>
<pre id="jadeinput" style="display:none">
- console.log(petlist)
h1 List
ul.list
- for(var i in petlist)
li= "Item - "+ petlist[i].name
- for(var j in petlist[i].pets)
li= "Pet - " + petlist[i].pets[j].name + " " + petlist[i].pets[j].type
</pre>
JavaScript
$(function() {
var json = {
"petlist" : [
{
"name" : "cats",
"pets":
[
{ "name":"Felix","type":"British short haired"}
]
},
{
"name" : "dogs",
"pets":
[
{"name":"Fido","type":"Labrador"}
]
},
{
"name" : "fish",
"pets":
[
{"name":"Bob","type":"Goldfish"}
]
},
{
"name" : "birds",
"pets" :
[
{"name":"Polly","type":"Parrot"}
]
}
]};
$("#jadeoutput").html(jade.compile($("#jadeinput").html())(json));
});
I have an JSON array like this
var filter_value_data = [{"Status":[{"name":"Open","id":"1"},{"name":"Pending","id":"2"},{"name":"Resolved","id":"3"},{"name":"Closed","id":"4"},{"name":"Evaluation","id":"5"}]},{"Payment Status":[{"name":"Paid","id":"10"},{"name":"UnPaid","id":"11"},{"name":"Part Paid","id":"12"}]},{"Priority":[{"name":"Low","id":"6"},{"name":"Medium","id":"7"},{"name":"High","id":"8"},{"name":"Urgent","id":"9"}]}]
I have tried filter_value_data["Status"] which is obviously wrong. How do I get the JSON elements for Status using the names like Status,Payment Status?
filter_value_data is an array (having []), so use filter_value_data[0].Status to get the first element-object with property "Status".
It is always good to format your code in order to see the hierarchy of the structures:
var filter_value_data = [
{
"Status": [
{
"name": "Open",
"id": "1"
}, {
"name": "Pending",
"id": "2"
}, ...
]
}, {
"Payment Status": [
{
"name": "Paid",
"id": "10"
}, ...
]
}, {
"Priority": [
{
"name": "Low",
"id": "6"
}, ...
]
}
];
With your current JSON you can't get the elements with the name alone.
You can get Status with filter_value_data[0]['Status'] and Payment status with filter_value_data[1]['Payment Status'].
This is because the keys are in seperate objects in the array.
In order to get them with filter_value_data['Status'] you need to change your JSON to
var filter_value_data = {
"Status":[
{"name":"Open","id":"1"},
{"name":"Pending","id":"2"},
{"name":"Resolved","id":"3"},
{"name":"Closed","id":"4"},
{"name":"Evaluation","id":"5"}
],
"Payment Status":[
{"name":"Paid","id":"10"},
{"name":"UnPaid","id":"11"},
{"name":"Part Paid","id":"12"}
],
"Priority":[
{"name":"Low","id":"6"},
{"name":"Medium","id":"7"},
{"name":"High","id":"8"},
{"name":"Urgent","id":"9"}
]
};
I wrote this on my phone so it's not as well-formatted as usual. I'll change it ASAP.
With your current JSON, created a result which might be helpful for you.
JS:
$.each(filter_value_data,function(ind,val){
var sta = val.Status; // Status Object get displayed
for(var i=0;i<sta.length;i++){
var idVal= sta[i].id;
var nameVal = sta[i].name;
Statusarray.push(idVal,nameVal);
console.log(Statusarray);
}
})
FiddleDemo
You can use below code, it will return status object
filter_value_data[0]['Status']
filter_value_data[0]['Payment Status']
to get Single value you use :
filter_value_data[0]['Status'][0]['name']