Looping Through Nested JSON with Nested Child Searches - javascript

I have a JSON structure that looks like this:
"benefitValues" : [ {
"changeDate" : "2017-10-13T20:26:13.000+0000",
"changeUserName" : "aaaa",
"numericValue" : 20,
"value" : "20",
"amountType" : {
"allowCustomDataFlg" : false,
"dataType" : "Percent",
"defaultTypeFlg" : true,
"defaultValue" : "Unlimited",
"description" : null,
"maxValue" : null,
"minValue" : null,
"name" : "LIST",
"benefit" : {
"category" : "Facility Services",
"name" : "Single Limit",
"networkStatus" : "IN_NETWORK",
"planType" : "MedicalPlan",
"sortOrder" : 20,
"subcategory" : "Acupuncture Treatment",
"subcategorySortOrder" : 6
}
}
}]
Based on the string "Acupuncture Treatment", I need to extract the the value and the datatype. The dataset is very large, with hundreds of subcategories. I cannot find a good way to search through this data. I tried json-path and advanced-json-path, but if I do a search on a child element, there is no way for me to return the parents. I want my output to look like this:
{
"Subcategory" : "Acupuncture Treatment",
"Value" : "20",
"Type" : "Percent"
}
I was hoping there was an easy way to do this with an existing library, or at least with a simple loop.

This will find the matching element frombenefitValues, and transform the element into the format you're expecting:
var benefitValues = [{
"changeDate": "2017-10-13T20:26:13.000+0000",
"changeUserName": "aaaa",
"numericValue": 20,
"value": "20",
"amountType": {
"allowCustomDataFlg": false,
"dataType": "Percent",
"defaultTypeFlg": true,
"defaultValue": "Unlimited",
"description": null,
"maxValue": null,
"minValue": null,
"name": "LIST",
"benefit": {
"category": "Facility Services",
"name": "Single Limit",
"networkStatus": "IN_NETWORK",
"planType": "MedicalPlan",
"sortOrder": 20,
"subcategory": "Acupuncture Treatment",
"subcategorySortOrder": 6
}
}
}];
// Find the element
let treatment = benefitValues.find((item) => item.amountType.benefit.subcategory === 'Acupuncture Treatment');
let result = {
Value: treatment.value,
Subcategory: treatment.amountType.benefit.subcategory,
Type: treatment.amountType.dataType
}
console.log(result);

You can search through your data set and pull out only the items that match your string by using .filter. That would give you the entire object, so then you can use .map to transform it to the structure you want.
Or if you're only interested in the first result, you can use .find instead.
const json = {"benefitValues" : [{
"changeDate" : "2017-10-13T20:26:13.000+0000",
"changeUserName" : "aaaa",
"numericValue" : 20,
"value" : "20",
"amountType" : {
"allowCustomDataFlg" : false,
"dataType" : "Percent",
"defaultTypeFlg" : true,
"defaultValue" : "Unlimited",
"description" : null,
"maxValue" : null,
"minValue" : null,
"name" : "LIST",
"benefit" : {
"category" : "Facility Services",
"name" : "Single Limit",
"networkStatus" : "IN_NETWORK",
"planType" : "MedicalPlan",
"sortOrder" : 20,
"subcategory" : "Acupuncture Treatment",
"subcategorySortOrder" : 6
}
}
}]};
// With filter/map
const result = json.benefitValues
.filter(val => val.amountType.benefit.subcategory === "Acupuncture Treatment")
.map(val => ({Subcategory: val.amountType.benefit.subcategory, Value: val.value, Type: val.amountType.dataType}));
console.log(result)
// With find / manual transform:
const singleFullResult = json.benefitValues
.find(val => val.amountType.benefit.subcategory === "Acupuncture Treatment")
const singleResult = {
Subcategory: singleFullResult.amountType.benefit.subcategory,
Value: singleFullResult.value,
Type: singleFullResult.amountType.dataType
}
console.log(singleResult)

You can use Array.prototype.filter() combined with Array.prototype.map() and create an array of object with the structure you need. Here's an example:
let myArray = [{
"changeDate": "2017-10-13T20:26:13.000+0000",
"changeUserName": "aaaa",
"numericValue": 20,
"value": "20",
"amountType": {
"allowCustomDataFlg": false,
"dataType": "Percent",
"defaultTypeFlg": true,
"defaultValue": "Unlimited",
"description": null,
"maxValue": null,
"minValue": null,
"name": "LIST",
"benefit": {
"category": "Facility Services",
"name": "Single Limit",
"networkStatus": "IN_NETWORK",
"planType": "MedicalPlan",
"sortOrder": 20,
"subcategory": "Acupuncture Treatment",
"subcategorySortOrder": 6
}
}
}];
let ret = myArray
.filter(arr => arr.amountType.benefit.subcategory === 'Acupuncture Treatment')
.map(arr => {
return {
Subcategory: arr.amountType.benefit.subcategory,
Value: arr.value,
Type: arr.amountType.dataType
};
});
console.log(ret);
First the filter function will filter your array and return only the items related to 'Acupuncture Treatment', then the map function, that receives as a parameter a function that will be executed for each item inside the array and it will return a new structure, will return only the fields you need.

Related

How to bulk insert JSON array of objects in MySQL in NodeJS

I'm basically trying to bulk insert or update (on duplicate key) a JSON array of objects in a MySQL table using NodeJS. Sometimes JSON objects in array contain different key-value pairs.
A possible solution could be to loop over the JSON array first and then search each object for every key hardcoded from another array (corresponding to columns in table) then push result values in new array of arrays. In case a key does not exist in JSON object then fill with a "NULL" value.
Many thanks for any advice in advance!
var keys = ['customerId','subscriptionId','billingMethod','skuId','creationTime','planName','isCommitmentPlan','startTime','endTime','numberOfSeats','licensedNumberOfSeats','maximumNumberOfSeats','isInTrial','trialEndTime','renewalType','purchaseOrderId','status''customerDomain','skuName','suspensionReasons','dealCode'];
var demo_api = [{
"kind": "reseller#subscription",
"customerId": "C0123456",
"subscriptionId": "123",
"billingMethod": "ONLINE",
"skuId": "Google-Apps-Unlimited",
"creationTime": "1331647980142",
"plan": {
"planName": "ANNUAL",
"isCommitmentPlan": true,
"commitmentInterval": {
"startTime": "1331647980142",
"endTime": "1363183980142"
}
},
"seats": {
"kind": "subscriptions#seats",
"numberOfSeats": 10,
"licensedNumberOfSeats": 10,
"maximumNumberOfSeats": 500
},
"trialSettings": {
"isInTrial": false
},
"renewalSettings": {
"kind": "subscriptions#renewalSettings",
"renewalType": "SWITCH_TO_PAY_AS_YOU_GO"
},
"purchaseOrderId": "my_example.com_annual_1",
"status": "ACTIVE",
"customerDomain": "my_example.com",
"skuName": "G Suite Business"
},
{
"kind": "reseller#subscription",
"customerId": "D0123456",
"subscriptionId": "456",
"billingMethod": "ONLINE",
"skuId": "Google-Apps-For-Business",
"creationTime": "1331647980142",
"plan": {
"planName": "FLEXIBLE",
"isCommitmentPlan": false
},
"seats": {
"kind": "subscriptions#seats",
"licensedNumberOfSeats": 0,
"maximumNumberOfSeats": 10
},
"trialSettings": {
"isInTrial": false
},
"purchaseOrderId": "my_example_flex_1",
"status": "ACTIVE",
"customerDomain": "my_example2.com",
"skuName": "G Suite Business"
}];
Desired result:
var result = [
["C0123456", "123", "ONLINE", "Google-Apps-Unlimited", "1331647980142", "ANNUAL", true, "1331647980142", "1363183980142", 10, 10, 500, false, "NULL", "SWITCH_TO_PAY_AS_YOU_GO", "my_example.com_annual_1", "ACTIVE", "my_example.com", "G Suite Basic", "NULL", "NULL"],
["D0123456", "456", "ONLINE", "Google-Apps-For-Business", "1331647980142", "FLEXIBLE", false, "NULL", "NULL", "NULL", 0, 0, false, "NULL", "NULL", "my_example_flex_1", "ACTIVE", "my_example2.com", "G Suite Business", "NULL", "NULL"]
];
you can try something like this:
var myArray = new Array();
data.forEach((player) => {
console.log(player.id);
console.log(player);
var playerModel ={
id : player.id,
firstname : player.firstname,
lastname : player.lastname,
position : player.position,
price : player.price,
appearences : player.appearences,
goals : player.goals,
assists : player.assists,
cleansheets : player.cleansheets,
redcards : player.redcards,
yellowcards : player.yellowcards,
image : player.image,
clubid : player.clubid,
};
console.log("model"+playerModel.position);
myArray.push(playerModel);
});
Here you need to change the model player in my code by a model created by you , and replace like this, just follow your json endpoint :
var Mymodel = {
bind: player.bind,
............
....
}
the last step is that myArray is your results array , you need to loop it to see results
for(let item of myArray) {
console.log(item);
console.log(item.bind);
.......................
}

Getting empty data while trying to get desired format of object

I have an object
"data" : [
{
"name" : "Heading",
"text" : "Text Heading",
"type" : "string",
"values" : [
"Arthur"
]
},
{
"name" : "Source",
"text" : "Source Reference",
"type" : "string",
"values" : [
"Jhon"
]
},
{
"name" : "Place",
"text" : "Bank Building",
"type" : "string",
"values" : [
"Mark"
]
},
{
"name" : "Animal",
"text" : "Branch",
"type" : "string",
"values" : [
"Susan"
]
}
]
there is a function i am passing the object and an array as the arguments
fieldArray=["Heading", "Animal"]
myFunction(fieldArray, data){
... your code here
}
I need to get the output in the below format where I have to search the object with the fields in myArray with the name key of data. Then I need to put the value of the searched object in the below format
[{
"id": 1,
"cells": [{
"id": "ConstId",
"cellContent": "Heading"
},
{
"id": "ConstValue",
"cellContent": "Arthur"
}
]
},
{
"id": 2,
"cells": [{
"id": "ConstId",
"cellContent": "Animal"
},
{
"id": "ConstValue", //a constant field name as ConstValue
"cellContent": "Susan" // the value of the second field in the myArray from object with name Animal
}
]
}
]
I have tried this
const getFormattedData = (fieldArray: any, data: any) => {
let innerData: any = [];
for (let i=0; i<fieldArray.length; i++){
const indexNumber = data.find((key: any) => key.name === fieldArray[i])
if(indexNumber != undefined){
innerData.push({
id: i+1,
cells:[{
id: 'inquiryName',
cellContent: indexNumber.name
},
{
id: 'value',
cellContent: indexNumber.values.toString()
}
]
})
}
console.log('innerData :>> ', innerData);
}
}
You could use the below. Since you tagged javascript, posting answer in JS.
function formatData(data, fieldArray) {
let ret = [];
fieldArray.forEach((field, i) => {
let dataObj = data.filter(d => d.name === field)[0]
if( dataObj ) {
ret.push({
"id": 1,
"cells": [{
"id": "ConstId",
"cellContent": field
},
{
"id": "ConstValue",
"cellContent": dataObj.values[0] //Put whole obj or just first
}
]
})
}
})
return ret;
}
Link to plnkr

iterate an array and collect specific data at any match of and additionally provided property value

I have a data structure that looks like this:
var data2 = {
"name" : "history",
"list": [{
"type" : "a",
"max" : 52.346377,
"min" : 0.1354055,
"date": "17-01-01",
"time": "21:38:17"
}, {
"type" : "b",
"max" : 55.3467377,
"min" : 0.1154055,
"date": "17-01-01",
"time": "22:38:17"
}, {
"type" : "b",
"max" : 48.3467377,
"min" : -0.1354055,
"date": "17-01-01",
"time": "23:38:17"
}]
}
I'd like to be able to iterate this data's list property and check if a list item's type value matches another provided value. Then if so, I'd like to collect the max and min values.
How could one achieve this task? I do not know how to figure this one out.
Thanks.
You can use a simple for ... of loop for example;
let checkType = "a";
let max, min;
for (let entry of data2.list) {
if (entry.type === checkType) {
max = entry.max;
min = entry.min;
break;
}
}
console.log(min, max);
Now let's beware this will stop at the first occurence of the right "type" (in case you have multiple entries with the same type);
If you want to account for multiple entries of the same "type", you could combine a filter and map iteration, for example :
let checkType = "b";
let minMaxValues = data2.list
.filter(e => e.type === checkType)
.map(e => { min : e.min, max : e.max });
console.log(minMaxValues);
/*
[{
min : 0.1154055,
max : 55.3467377
},
{
min : -0.1354055,
max : 48.3467377
}] */
"... I wanted all the max and min values for a particular value of type, not the absolute max and absolute min. Any way to include this?"
The probably most natural/obvious approach was to first filter any list item of a provided matching type ...
data2.list.filter(item => item.type === typeToCheckFor)
... and in a second step to map any item of the filtered array ...
.map(item => { min: item.min, max: item.max });
Another approach was to reduce the result within one iteration cycle ...
var data2 = {
"name" : "history",
"list": [{
"type" : "a",
"max" : 52.346377,
"min" : 0.1354055,
"date": "17-01-01",
"time": "21:38:17"
}, {
"type" : "b",
"max" : 55.3467377,
"min" : 0.1154055,
"date": "17-01-01",
"time": "22:38:17"
}, {
"type" : "b",
"max" : 48.3467377,
"min" : -0.1354055,
"date": "17-01-01",
"time": "23:38:17"
}]
}
function collectMinMaxValuesOfMatchingType(collector, item) {
if (item.type === collector.type) {
collector.list.push({
//type: item.type,
min: item.min,
max: item.max
})
}
return collector;
}
console.log(
data2.list.reduce(collectMinMaxValuesOfMatchingType, {
type: 'b',
list: []
}).list
);
console.log(
data2.list.reduce(collectMinMaxValuesOfMatchingType, {
type: 'a',
list: []
}).list
);
console.log(
data2.list.reduce(collectMinMaxValuesOfMatchingType, {
type: 'foo',
list: []
}).list
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Use filter on data.list will only deliver those objects whose type is identical to the searched value. Afterwards using map to create new objects with the min/max-values.
function filterArray(array, value) {
let result = array.list.filter( obj => obj.type===value).map( filtered => {
return {max: filtered.max, min: filtered.min}
});
return result;
}
var data2 = {
"name" : "history",
"list": [
{
"type" : "a",
"max" : 52.346377,
"min" : 0.1354055,
"date": "17-01-01",
"time": "21:38:17"
},
{
"type" : "b",
"max" : 55.3467377,
"min" : 0.1154055,
"date": "17-01-01",
"time": "22:38:17"
},
{
"type" : "b",
"max" : 48.3467377,
"min" : -0.1354055,
"date": "17-01-01",
"time": "23:38:17"
}
]
}
console.log(filterArray(data2,'b'));
console.log(filterArray(data2,'a'));
console.log(filterArray(data2,'any'));

Select particular field with condition satisfied in child in mongoDB using sails

I am having a mongoDB collection and the JSON looks like
[{
class : "I",
subject : "Maths",
students: [{
name : "John",
roll_no : "1001",
marks : "65",
is_passed : "true"
},
{
name : "Leo",
roll_no : "1002",
marks : "48",
is_passed : "false"
}]
}]
I am able to get the data using the command
My_Table_Name.find({}, {fields:{
'class' : 1,
'students':1
}
})
.populate('students',{
select : ['name', 'is_passed']
})
by this I can get the output as
[{
class : "I",
students : [{
name : "John",
is_passed : "true"
},
{
name : "Leo",
is_passed : "false"
}]
}]
but I need to get is_passed key only when it has true value,
my expected JSON is
[{
class : "I",
students : [{
name : "John",
is_passed : "true"
},
{
name : "Leo"
}]
}]
here in class I Leo has failed, so I do not need that field.
Please help to get through this problem, thanks in advance

Dojo Enhaced Grid - JsonRestStore, Grid is not showing data when use JsonRestStore

I have a json like
[
{
"switchType": {
"name": "sansayv15",
"perform": false,
"createBy": null,
"createDate": null,
"intId": 1,
"id": 1
},
"collectorType": {
"name": "FTP",
"perform": false,
"createBy": null,
"createDate": null,
"intId": 1,
"id": 1
},
"fileType": {
"name": "TEXT",
"perform": false,
"createBy": null,
"createDate": null,
"intId": 1,
"id": 1
},
"exportType": {
"name": "DB",
"perform": false,
"createBy": null,
"createDate": null,
"intId": 1,
"id": 1
},
"linesToSkip": "1",
"checkValidate": "true",
"checkDuplicate": "true",
"driver": "com.mysql.jdbc.Driver",
"url": "jdbc:mysql://localhost:3306/panamaxmediation",
"tableName": "sansayv15",
"ftpIp": null,
"ftpPort": null,
"ftpUserName": null,
"ftpPassword": null,
"sftpIp": null,
"sftpPort": null,
"sftpUserName": null,
"sftpPassword": null,
"name": "sansayv15",
"password": "root",
"userName": "root",
"perform": false,
"createBy": null,
"createDate": null,
"intId": 1,
"id": 1
}
]
Which comes as a output from my service.
I utilize this output in two stores JsonResStore and ObjectStore over MemorryStore for the EnhancedGrid
I have grid structure defined in variable ,
var templateGridStructure = [ {
name : "ID",
field : "id",
hidden : "true"
}, {
name : "Name",
field : "name",
width : "auto"
}, {
name : "Collection Method",
field : "_item",
width : "auto",
formatter : function(item) {
return item.collectorType.name;
}
}, {
name : "Export Method",
field : "_item",
width : "auto",
formatter : function(item) {
return item.exportType.name;
}
}, {
name : "Source File Type",
field : "_item",
width : "auto",
formatter : function(item) {
return item.fileType.name;
}
},{
name : "Duplication Check",
field : "checkDuplicate",
width : "auto",
},{
name : "Validation Check",
field : "checkValidate",
width : "auto",
},{
name : "Switch Type",
field : "_item",
width : "auto",
formatter : function(item) {
return item.switchType.name;
}
} ];
When I use ObjectStore in EnhancedGrid
templateGrid = new dojox.grid.EnhancedGrid({
id : "templateGrid",
name : "templateGrid",
store : objectStore});
Grid is showing correct data
But when I use JsonRestStore in EnhancedGrid
templateGrid = new dojox.grid.EnhancedGrid({
id : "templateGrid",
name : "templateGrid",
store : jsonRestStore});
I get error- grid is not showing data.
Is there any difference in defining column structure between these two stores.??
I found mistake, courtesy : Dojo IRC
"Ravi: you shouldn't be accessing items of dojo/data stores directly"
Instead of, directly using item in formatter method
{
name : "Switch Type",
field : "_item",
width : "auto",
formatter : function(item) {
return item.switchType.name;
}
}
use store.getValue(item,property), JsonRestStore, don't allow direct access to items
{
name : "Switch Type",
field : "_item",
width : "auto" ,
formatter : function(item) {
return store.getValue(item,"switchType").name;
}
}
I hope, somebody will get help from this

Categories

Resources