JSON calculate total number of particular Array object and result grouping - javascript

I have the following JSON data output from firebug console and I am trying to count the total number of the second item "Open" and group the result by Team. I am pulling the data from our SharePoint list.
"d":
{
"results":
[
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(53)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(53)",
"etag": ""18"",
"type": "SP.Data.TasksListItem"
},
"Team": "Team A",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(54)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(54)",
"etag": ""97"",
"type": "SP.Data.TasksListItem"
},
"Team": "Team B",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(82)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(82)",
"etag": ""65"",
"type": "SP.Data.TasksListItem"
},
"Team": "Team B",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(97)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(97)",
"etag": ""18"",
"type": "SP.Data.TasksListItem"
},
"Team": "Team C",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(99)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(99)",
"etag": ""8"",
"type": "SP.Data.TasksListItem"
},
"Team": "Team E",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(106)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(106)",
"etag": ""44"",
"type": "SP.Data.TasksListItem"
},
"Team": "Team D",
"taskStatus": "Open"
},
I have used the following JavaScript and I am getting only a value that is not correct. I only get 3, which is not correct. It should be 300 or more. For the sake of brevity I am only posting an excerpt of my JSON data.
// JavaScript source code
$.ajax({
url: _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/GetByTitle('Teams')/Items?$filter=taskStatus eq 'Open'&$select=Team,taskStatus",
type: "GET",
dataType: "json",
async: "true",
headers: {
"accept": "application/json;odata=verbose",
},
success: function (data) {
var dataArray = [];
var countArray = [];
var results = data.d.results;
for (var i = 0; i < results.length; i++){
for (key in results[i]) {
if (results[i].hasOwnProperty(key)) {
countArray.push(results[i][key]);
}
}
}
for (var i = 0; i < results.length; i++){
var team = Object.keys(results[1]).length; //This is returning only the value of 3
console.log(team);
}
console.log(countArray);
},
error: function(err) {
alert(JSON.stringify(err));
}
});
Can you please assist in solving this?
I have revised the raw JSON data as requested to reflect what I get from the server.

The output of console.log(team) is always 3 because when you call Object.keys(results[1]).length you are just finding the number of properties (keys) in the first result object (from your sample JSON data).
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(53)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(53)",
"etag": "18",
"type": "SP.Data.TasksListItem"
},
"Team": "Team A",
"taskStatus": "Open"
}
A simple loop over the results can group them:
var results = data.d.results;
var openCount = results.length;
var groupedResults = {};
//Total number of open tasks
console.log(openCount);
for (var i = 0; i < openCount; i++) {
var team = results[i]["Team"]
if (!groupedResults[team]) {
groupedResults[team] = [];
}
groupedResults[team].push(results[i]);
}
//Open tasks grouped by team
console.log(groupedResults);
//Count of open tasks for "Team B"
console.log(groupedResults["Team B"].length);
See the code snippet below for a fully functional demo based using your sample data.
var data = {
"d":
{
"results":
[
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(53)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(53)",
"etag": "18",
"type": "SP.Data.TasksListItem"
},
"Team": "Team A",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(54)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(54)",
"etag": "97",
"type": "SP.Data.TasksListItem"
},
"Team": "Team B",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(82)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(82)",
"etag": "65",
"type": "SP.Data.TasksListItem"
},
"Team": "Team B",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(97)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(97)",
"etag": "18",
"type": "SP.Data.TasksListItem"
},
"Team": "Team C",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(99)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(99)",
"etag": "8",
"type": "SP.Data.TasksListItem"
},
"Team": "Team E",
"taskStatus": "Open"
},
{
"__metadata":
{
"id": "Web/Lists(guid'1234578785596655')/Items(106)",
"uri": "https://spteamsite.com/_api/web/lists/GetByTitle('Teams')/Items(106)",
"etag": "44",
"type": "SP.Data.TasksListItem"
},
"Team": "Team D",
"taskStatus": "Open"
}
]
}
};
function printResult(value) {
var d = document.createElement('div');
d.innerHTML = JSON.stringify(value);
document.body.appendChild(d);
console.log(value);
}
var results = data.d.results;
var openCount = results.length;
var groupedResults = {};
//Total number of open tasks
printResult("Open tasks for all teams: " + openCount);
for (var i = 0; i < openCount; i++) {
var team = results[i]["Team"]
if (!groupedResults[team]) {
groupedResults[team] = [];
}
groupedResults[team].push(results[i]);
}
//Open tasks grouped by team
printResult(groupedResults);
//Count of open tasks for "Team B"
printResult("Open tasks for Team B: " + groupedResults["Team B"].length);
div {
border: 1px solid black;
margin: 10px;
}

If I understand your question correctly you want to group by Team then get sum of open.
Using linq.js it is easy
var aggregatedObject = Enumerable.From(data).GroupBy("$.Team", null,function (key, g) {
return {
Team: key,
Open: g.Sum("$.Open")
}
}).ToArray();
Edited
var query = Enumerable.From(jsonObject)
.GroupBy(
"$.City",
null,
"{ City: $, Count: $$.Count() }").ToArray()

Related

obj[i] is not iterable in javascript while transforming data

I am trying to transform my data from one format to another format , but I am getting error obj[i] is not iterable why I want to get expected output as shown below in variable
const data = {
"GENERAL": {
"value": null,
"type": "LABEL",
},
"Mobile NUMBER": {
"value": "04061511",
"type": "FIELD",
},
"Abc NUMBER": {
"value": "89999",
"type": "FIELD",
},
"Personal Info": {
"value": null,
"type": "LABEL",
},
"Address": {
"value": "g-78",
"type": "FIELD",
}, "local": {
"value": "090099",
"type": "FIELD",
}
}
const obj = {}
for (var i in data) {
const {type} = data[i];
if (type === 'LABEL') {
obj[i] = []
} else {
obj[i] = [...obj[i], data[i]]
}
}
console.log(obj)
const expectedout = {
"GENERAL": [{
"value": "04061511",
"type": "FIELD",
"displaytext": "Mobile NUMBER"
}, {
"value": "89999",
"type": "FIELD",
"displaytext": "Abc NUMBER"
}],
"Personal Info": [{
"value": "g-78",
"type": "FIELD",
"displaytext": "Address"
}, {
"value": "090099",
"type": "FIELD",
"displaytext": "local"
}]
}
Is there any better approach to transform my current data to expected data?I am ES6 in react
here is my code
https://jsbin.com/sesipuzeni/1/edit?html,js,console,output
Update
var obj = {
"first":"first",
"2":"2",
"34":"34",
"1":"1",
"second":"second"
};
for (var i in obj) { console.log(i); };
VM5628:8
it seems object property don't have guarantee.yes is correct when you have number and string
but when you have always "string" it comes in same order
var obj = {
"first":{a:"jjj"},
"yyy":{a:"jjqej"},
"ttt":{a:"jjsqj"},
"ggg":{a:"jjjs"},
"second":{a:"jjcj"}
};
for (var i in obj) { console.log(i); };
The problem is that when you're processing the next element of the original object, i is no longer the key of the element containing the array of values. You need to save that in another variable.
const data = {
"GENERAL": {
"value": null,
"type": "LABEL",
},
"Mobile NUMBER": {
"value": "04061511",
"type": "FIELD",
},
"Abc NUMBER": {
"value": "89999",
"type": "FIELD",
},
"Personal Info": {
"value": null,
"type": "LABEL",
},
"Address": {
"value": "g-78",
"type": "FIELD",
},
"local": {
"value": "090099",
"type": "FIELD",
}
}
const obj = {};
var lastLabel;
for (var i in data) {
if (data[i].type === 'LABEL') {
obj[i] = []
lastLabel = i;
} else {
data[i].displaytext = i;
obj[lastLabel] = [...obj[lastLabel], data[i]]
}
}
console.log(obj)
Note that this whole approach depends on object properties retaining their order, which isn't guaranteed in JavaScript. But it happens to work in most existing implementations, I think.

Javascript map is not a function what trying to read data

I am trying to populate a chart so I'm getting the data into 2 lists in order to do this.
This is the data:
var data = [{
"id": "622",
"name": "some name",
"boats": {
"637": {
"id": "637",
"name": " Subcat 1",
"translations": null
},
"638": {
"id": "638",
"name": "Subcat 2",
"translations": null
}
},
"image": "73e043a7fae04b55855bede22da6286b"
}];
And I am running this code in order to populate the lists:
var chList = [];
var boatList = [];
var boatCount = [];
for (var i = 0; i < data.length; i++) {
var obj = data[i];
var cl = obj.name + " [" + obj.id + "]";
if (obj.boats != null) {
chList.push(cl);
}
if(obj.boats) {
var nme = obj.boats.map( function(item){
return item.name;
});
boatList = boatList.concat(nme);
boatCount.push(nme.length);
}
}
console.log(boatList);
console.log(boatCount);
My problem is that I keep getting:
TypeError: obj.boats.map is not a function
How can I fix this?
Note: The data is actually this:
{
"id": "622",
"name": "some name",
"boats": {
"637": {
"id": "637",
"name": " Subcat 1",
"translations": null
},
"638": {
"id": "638",
"name": "Subcat 2",
"translations": null
}
},
"image": "73e043a7fae04b55855bede22da6286b"
};
But I added [ and ] to it in order to use data.length and the lists where empty too ... Do I then leave this data as it is?
The problem is that obj.boats is an object, not an array, hence doesn't have the map method.
Try this instead:
Object.keys(obj.boats).map(function(k) { return obj.boats[k].name; });
See MDN
boats is an object, not an array. Map is for arrays.
You could use a for ( in ) loop or Object.keys() to get an array of keys and work with that.
The two other answers are right, I'd change the data though:
"boats": [
{
"id": "637",
"name": " Subcat 1",
"translations": null
},
{
"id": "638",
"name": "Subcat 2",
"translations": null
}
],
Using the id as key and then giving the containing object a "id" property is kinda pointless. When you change the data to this structure your code will work fine.
Besides all other answers that already correctly point to obj.boats being an Object and not an Array, I'd like providing a solution that demonstrates the elegant beauty of Array.reduce ...
var boatChartData = [{
"id": "622",
"name": "some name",
"boats": {
"637": {
"id": "637",
"name": "Subcat 1",
"translations": null
},
"638": {
"id": "638",
"name": "Subcat 2",
"translations": null
}
},
"image": "73e043a7fae04b55855bede22da6286b"
}, {
"id": "623",
"name": "other name",
"boats": {
"639": {
"id": "639",
"name": "Supercat",
"translations": null
},
"640": {
"id": "640",
"name": "Supercat II",
"translations": null
},
"641": {
"id": "641",
"name": "Supercat III",
"translations": null
}
},
"image": "73e043a7fae04b55855bede22da6295c"
}];
function collectBoatChartData(collector, chartItem/*, idx, list*/) {
var
boatNameList,
boatMap = chartItem.boats;
if (boatMap != null) {
collector.chartItemTitleList.push([
chartItem.name,
" [",
chartItem.id,
"]"
].join(""));
boatNameList = Object.keys(boatMap).map(collector.getBoatNameByKey, boatMap);
collector.boatNameList = collector.boatNameList.concat(boatNameList);
//collector.chartItemBoatNameList.push(boatNameList);
collector.chartItemBoatCountList.push(boatNameList.length);
}
return collector;
}
var processedBoatChartData = boatChartData.reduce(collectBoatChartData, {
getBoatNameByKey: function (key) {
return this[key].name;
},
boatNameList: [],
chartItemTitleList: [],
//chartItemBoatNameList: [],
chartItemBoatCountList: []
});
console.log("processedBoatChartData.boatNameList : ", processedBoatChartData.boatNameList);
console.log("processedBoatChartData.chartItemTitleList : ", processedBoatChartData.chartItemTitleList);
//console.log("processedBoatChartData.chartItemBoatNameList : ", processedBoatChartData.chartItemBoatNameList);
console.log("processedBoatChartData.chartItemBoatCountList : ", processedBoatChartData.chartItemBoatCountList);
Note
Taking into account the OP's additional comment, mentioning the provided axample's real data structure, the above provided solution of mine just changes to ...
var boatChartData = {
"id": "622",
"name": "some name",
"boats": {
"637": {
"id": "637",
"name": "Subcat 1",
"translations": null
},
"638": {
"id": "638",
"name": "Subcat 2",
"translations": null
}
},
"image": "73e043a7fae04b55855bede22da6286b"
};
var processedBoatChartData = [boatChartData].reduce(collectBoatChartData, {
getBoatNameByKey: function (key) {
return this[key].name;
},
boatNameList: [],
chartItemTitleList: [],
//chartItemBoatNameList: [],
chartItemBoatCountList: []
});
.., proving that generic solutions can be recycled/adapted easily, if e.g. data structures do change.

Javascript multiple drop down box

Is there a way to get a multiple drop down field from a list of arrays without having to hardcode the information into the HTML? So that by selecting each category the relevant subcategory will drop down.
The list looks something like this:
var listData = [
{
"title": "Meeting Room",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Book a Car",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Stationery",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Hospitality",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Communications",
"category": "News",
"url": "https://blogs.office.com/"
},
{
"title": "Industries",
"category": "News",
"url": "https://blogs.office.com/"
},
{
"title": "Policy",
"category": "News",
"url": "https://blogs.office.com/"
},
{
"title": "Get started",
"category": "Information",
"url": "https://support.office.com/"
},
{
"title": "What do you need",
"category": "Useful Information",
"url": "https://support.office.com/"
},
{
"title": "Accessibility features",
"category": "Useful Information",
"url": "https://support.office.com/"
},
{
"title": "Videos",
"category": "Useful Information",
"url": "https://support.office.com/"
}
]
The following code does the work. It's vanilla JS.
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Form</title>
</head>
<body>
<select id="categories" onchange="changeCategory(event)"> </select>
<select id="title"> </select>
<select id="url"> </select>
<script>
var listData = [{
"title": "Meeting Room"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Book a Car"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Stationery"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Hospitality"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Communications"
, "category": "News"
, "url": "https://blogs.office.com/"
}, {
"title": "Industries"
, "category": "News"
, "url": "https://blogs.office.com/"
}, {
"title": "Policy"
, "category": "News"
, "url": "https://blogs.office.com/"
}, {
"title": "Get started"
, "category": "Information"
, "url": "https://support.office.com/"
}, {
"title": "What do you need"
, "category": "Useful Information"
, "url": "https://support.office.com/"
}, {
"title": "Accessibility features"
, "category": "Useful Information"
, "url": "https://support.office.com/"
}, {
"title": "Videos"
, "category": "Useful Information"
, "url": "https://support.office.com/"
}];
function removeOptions(selectbox) {
var i;
for (i = selectbox.options.length - 1; i >= 0; i--) {
selectbox.remove(i);
}
}
function changeCategory(event) {
removeOptions(document.getElementById('title'))
removeOptions(document.getElementById('url'))
mySelect1 = document.getElementById('title')
mySelect2 = document.getElementById('url');
listData.forEach(function (item, index) {
if (item.category == event.target.value) {
mySelect1.options[mySelect1.options.length] = new Option(item.title, item.title);
mySelect2.options[mySelect2.options.length] = new Option(item.url, item.url);
}
});
}
Array.prototype.contains = function (obj) {
var i = this.length;
while (i--) {
if (this[i] == obj) {
return true;
}
}
return false;
}
var mySelect = document.getElementById('categories');
var categories = new Array;
listData.forEach(function (item, index) {
if (!categories.contains(item.category)) {
mySelect.options[mySelect.options.length] = new Option(item.category, item.category);
categories.push(item.category);
}
});
</script>
</body>
</html>

I have a json object that I obtained from drafter and I only want the schema

I am using node to call drafter in order to generate the json schema for an application. My goal is to get rid of all the extra output that is spit out by drafter. I end up with a huge thing of json but I only need a small portion of it.
This is what is output:
{
"element": "parseResult",
"content": [
{
"element": "category",
"meta": {
"classes": [
"api"
],
"title": "Test"
},
"attributes": {
"meta": [
{
"element": "member",
"meta": {
"classes": [
"user"
]
},
"content": {
"key": {
"element": "string",
"content": "FORMAT"
},
"value": {
"element": "string",
"content": "1A"
}
}
}
]
},
"content": [
{
"element": "category",
"meta": {
"classes": [
"resourceGroup"
],
"title": "Questions"
},
"content": [
{
"element": "resource",
"meta": {
"title": "Questions"
},
"attributes": {
"href": "/questions"
},
"content": [
{
"element": "transition",
"meta": {
"title": "List All Questions"
},
"content": [
{
"element": "httpTransaction",
"content": [
{
"element": "httpRequest",
"attributes": {
"method": "GET"
},
"content": []
},
{
"element": "httpResponse",
"attributes": {
"statusCode": "200",
"headers": {
"element": "httpHeaders",
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "Content-Type"
},
"value": {
"element": "string",
"content": "application/json"
}
}
}
]
}
},
"content": [
{
"element": "dataStructure",
"content": [
{
"element": "Question List"
}
]
},
{
"element": "asset",
"meta": {
"classes": [
"messageBody"
]
},
"attributes": {
"contentType": "application/json"
},
"content": "[\n {\n \"question\": \"Favourite programming language?\",\n \"published_at\": \"2014-11-11T08:40:51.620Z\",\n \"url\": \"/questions/1\",\n \"choices\": [\n {\n \"choice\": \"Javascript\",\n \"url\": \"/questions/1/choices/1\",\n \"votes\": 2048\n }\n ]\n }\n]"
},
{
"element": "asset",
"meta": {
"classes": [
"messageBodySchema"
]
},
"attributes": {
"contentType": "application/schema+json"
},
"content": "{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"type\": \"array\"\n}"
}
]
}
]
}
]
}
]
},
{
"element": "resource",
"meta": {
"title": "Question"
},
"attributes": {
"href": "/questions/{id}",
"hrefVariables": {
"element": "hrefVariables",
"content": [
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "id"
},
"value": {
"element": "number",
"content": 1234
}
}
}
]
}
},
"content": [
{
"element": "transition",
"meta": {
"title": "Retrieve Question"
},
"content": [
{
"element": "httpTransaction",
"content": [
{
"element": "httpRequest",
"attributes": {
"method": "GET"
},
"content": []
},
{
"element": "httpResponse",
"attributes": {
"statusCode": "200",
"headers": {
"element": "httpHeaders",
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "Content-Type"
},
"value": {
"element": "string",
"content": "application/json"
}
}
}
]
}
},
"content": [
{
"element": "dataStructure",
"content": [
{
"element": "Question"
}
]
},
{
"element": "asset",
"meta": {
"classes": [
"messageBody"
]
},
"attributes": {
"contentType": "application/json"
},
"content": "{\n \"question\": \"Favourite programming language?\",\n \"published_at\": \"2014-11-11T08:40:51.620Z\",\n \"url\": \"/questions/1\",\n \"choices\": [\n {\n \"choice\": \"Javascript\",\n \"url\": \"/questions/1/choices/1\",\n \"votes\": 2048\n }\n ]\n}"
},
{
"element": "asset",
"meta": {
"classes": [
"messageBodySchema"
]
},
"attributes": {
"contentType": "application/schema+json"
},
"content": "{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"type\": \"object\",\n \"properties\": {\n \"question\": {\n \"type\": \"string\"\n },\n \"published_at\": {\n \"type\": \"string\"\n },\n \"url\": {\n \"type\": \"string\"\n },\n \"choices\": {\n \"type\": \"array\"\n }\n },\n \"required\": [\n \"question\",\n \"published_at\",\n \"url\",\n \"choices\"\n ]\n}"
}
]
}
]
}
]
}
]
}
]
},
{
"element": "category",
"meta": {
"classes": [
"dataStructures"
]
},
"content": [
{
"element": "dataStructure",
"content": [
{
"element": "object",
"meta": {
"id": "Question"
},
"content": [
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "question"
},
"value": {
"element": "string",
"content": "Favourite programming language?"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "published_at"
},
"value": {
"element": "string",
"content": "2014-11-11T08:40:51.620Z"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "url"
},
"value": {
"element": "string",
"content": "/questions/1"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "choices"
},
"value": {
"element": "array",
"content": [
{
"element": "Choice"
}
]
}
}
}
]
}
]
},
{
"element": "dataStructure",
"content": [
{
"element": "object",
"meta": {
"id": "Choice"
},
"content": [
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "choice"
},
"value": {
"element": "string",
"content": "Javascript"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "url"
},
"value": {
"element": "string",
"content": "/questions/1/choices/1"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "votes"
},
"value": {
"element": "number",
"content": 2048
}
}
}
]
}
]
},
{
"element": "dataStructure",
"content": [
{
"element": "array",
"meta": {
"id": "Question List"
},
"content": [
{
"element": "Question"
}
]
}
]
}
]
}
]
}
]
}
The bit below is what I need.
content = {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"question": {
"type": "string"
},
"published_at": {
"type": "string"
},
"url": {
"type": "string"
},
"choices": {
"type": "array"
}
},
"required": [
"question",
"published_at",
"url",
"choices"
]
}
This is the code I have as of right now and it is not working the way I am envisioning. If you need any more information to help me please ask.
App.js
var fs = require('fs');
var edit = require('string-editor');
var lodash = require('lodash');
var _ = require('underscore');
const util = require('util');
const exec = require('child_process').exec;
exec('drafter -f json test.apib' , function(error, stdout, stderr) {
const json = JSON.parse(stdout);
//console.log(json)
var res
function loopThrough(obj){
for(var key in obj){
if(!obj.hasOwnProperty(key)) continue;
if(typeof obj[key] !== 'object'){
//if (cond) var x = {'$schema': };
//if (_.hasIn(obj, '$schema')) {
res = res + "\n" + (key+" = "+obj[key]);
//}
} else {
loopThrough(obj[key]);
}
}
}
loopThrough(json);
//parse = JSON.parse(test);
//string = JSON.stringify(test, null, ' ');
//string = string.replace(/\\n/g, '');
fs.writeFile('test.json', res, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
if (error !== null) {
console.log('exec error: ' + error);
}
});
This is the ouput I am down to.
undefined
element = parseResult
element = category
0 = api
title = Test
element = member
0 = user
element = string
content = FORMAT
element = string
content = 1A
element = category
0 = resourceGroup
title = Questions
element = resource
title = Questions
href = /questions
element = transition
title = List All Questions
element = httpTransaction
element = httpRequest
method = GET
element = httpResponse
statusCode = 200
element = httpHeaders
element = member
element = string
content = Content-Type
element = string
content = application/json
element = dataStructure
element = Question List
element = asset
0 = messageBody
contentType = application/json
content = [
{
"question": "Favourite programming language?",
"published_at": "2014-11-11T08:40:51.620Z",
"url": "/questions/1",
"choices": [
{
"choice": "Javascript",
"url": "/questions/1/choices/1",
"votes": 2048
}
]
}
]
element = asset
0 = messageBodySchema
contentType = application/schema+json
content = {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array"
}
element = resource
title = Question
href = /questions/{id}
element = hrefVariables
element = member
0 = required
element = string
content = id
element = number
content = 1234
element = transition
title = Retrieve Question
element = httpTransaction
element = httpRequest
method = GET
element = httpResponse
statusCode = 200
element = httpHeaders
element = member
element = string
content = Content-Type
element = string
content = application/json
element = dataStructure
element = Question
element = asset
0 = messageBody
contentType = application/json
content = {
"question": "Favourite programming language?",
"published_at": "2014-11-11T08:40:51.620Z",
"url": "/questions/1",
"choices": [
{
"choice": "Javascript",
"url": "/questions/1/choices/1",
"votes": 2048
}
]
}
element = asset
0 = messageBodySchema
contentType = application/schema+json
content = {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"question": {
"type": "string"
},
"published_at": {
"type": "string"
},
"url": {
"type": "string"
},
"choices": {
"type": "array"
}
},
"required": [
"question",
"published_at",
"url",
"choices"
]
}
element = category
0 = dataStructures
element = dataStructure
element = object
id = Question
element = member
0 = required
element = string
content = question
element = string
content = Favourite programming language?
element = member
0 = required
element = string
content = published_at
element = string
content = 2014-11-11T08:40:51.620Z
element = member
0 = required
element = string
content = url
element = string
content = /questions/1
element = member
0 = required
element = string
content = choices
element = array
element = Choice
element = dataStructure
element = object
id = Choice
element = member
0 = required
element = string
content = choice
element = string
content = Javascript
element = member
0 = required
element = string
content = url
element = string
content = /questions/1/choices/1
element = member
0 = required
element = string
content = votes
element = number
content = 2048
element = dataStructure
element = array
id = Question List
element = Question
You could try running it through an online JSON schema generation tool like this: http://jsonschema.net/#/
You will also want to consider reading up on the proposed JSON Schema specification here: http://json-schema.org/documentation.html
UPDATED: If you would like to generate the schema at runtime via Node, you could leverage a module like json-schema-generator.
UPDATED AGAIN: I am not sure I follow you but, from looking at your data, you should be able to use the following to grab all content with the contentType of application/schema+json like so:
var _ = require('lodash');
var schemas = [];
function isSchemaType(contentItem) {
return _.get(contentItem, 'attributes.contentType') == 'application/schema+json';
}
function parseContent(content) {
if (_.isObject(content) && _.isArray(content.content)) {
_.forEach(content.content, parseContent);
} else if (isSchemaType(content)) {
schemas.push(JSON.parse(content.content));
}
}
parseContent(jsonData);
console.log(schemas);
Here is a working jsfiddle: https://jsfiddle.net/k7dcd6s2/

Jquery : transform nested json object to another json object

In javascript/jquery how do i achieve following
old_dataset = [
{
"dob": "xyz",
"name": {
"first": " abc",
"last": "lastname"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
},
{
"dob": "er",
"name": {
"first": " abc",
"last": "txt"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
}
]
Using jquery iterate over the above and change to following
new_dataset = [
{
"dob":"xyz",
"name": <first and last name values>
"start_date":<value of month day year>,
"children": [ {
child_id :1,
child_id : 2
},
]
},{
"dob":"er",
"name": <first and last name values>
"start_date":<value of month day year>,
"children": [ {
child_id :1,
child_id : 2
},
]
}]
If someone can give the code to transform the data it would help me to understand the iteration
You could do something like:
function transformDataset(oldDataset) {
var newDataset = [];
var newObj;
for (var i = 0; i < oldDataset.length; i++) {
newObj = transformObj(oldDataset[i]);
newDataset.push(newObj);
}
return newDataset;
}
function transformObj(obj) {
var children = obj.children;
obj.name = obj.name.first + ' ' + obj.name.last;
obj.start_date = obj.start_date.month + ' ' + obj.start_date.day + ' ' + obj.start_date.year;
obj.children = [];
for (var i = 0; i < children.length; i++) {
obj.children.push(children[i].child.id);
}
return obj;
}
var new_dataset = transformDataset(old_dataset);
Note that new_dataset will have an array of child id instead of an object with multiple child_id properties.
You also had a typo in old_dataset.start_date.month (was written moth)(or maybe that was intentional).
use map first to iterate the array data (old_dataset), replace element name & start_date with new value then return the array
const old_dataset = [
{
"dob": "xyz",
"name": {
"first": " abc",
"last": "lastname"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
},
{
"dob": "er",
"name": {
"first": " abc",
"last": "txt"
},
"start_date": {
"moth": "2",
"day": "5",
"year": 1
},
"children": [
{
"child": {
"id": "1",
"desc": "first child"
}
},
{
"child": {
"id": "2",
"desc": "second child"
}
}
]
}
]
let new_dataset = old_dataset.map((arr) => {
arr.name = `${arr.name.first} ${arr.name.last}`
arr.start_date = `${arr.start_date.moth} ${arr.start_date.day} ${arr.start_date.year}`
return arr
})
console.log(new_dataset)

Categories

Resources