Is there is a way to transform this JSON Object using Angular? I need to transform the JSON object from this format:
$scope.TestJson = {
"filters": [
{
"dataPropertyID": "VoidType",
"label": "Homeless"
},
{
"dataPropertyID": "VoidType",
"label": "Mainstream"
},
{
"dataPropertyID": "PropertyType",
"label": "Flat"
},
{
"dataPropertyID": "PropertyType",
"label": "Cottage"
}
]
}
To this format:
$scope.NewTestJson = {
"filters": [
{
"dataPropertyID": "VoidType",
"label":[ "Homeless","Mainstream"]
},
{
"dataPropertyID": "PropertyType",
"label":[ "Flat", "Cottage"]
}
]
}
I think this is more a JavaScript question than anything else. Nonetheless:
$scope.NewTestJson = {
filters: [];
};
// Do something for all (old) filter items
$scope.TestJson.filters.forEach(function(filter) {
// Try to get the existing (new) filter
var newFilter = $scope.NewTestJson.filters.filter(function(newFilter) {
return newFilter.dataPropertyID === filter.dataPropertyID;
}).shift();
// If the new filter does not exist, create it
if (!newFilter) {
newFilter = {
dataPropertyID: filter.dataPropertyID,
label: []
};
$scope.NewTestJson.filters.push(newFilter);
}
// Finally, add the old filter label to the new filter
newFilter.label.push(filter.label);
});
json = {
"filters": [
{
"dataPropertyID": "VoidType",
"label": "Homeless"
},
{
"dataPropertyID": "VoidType",
"label": "Mainstream"
},
{
"dataPropertyID": "PropertyType",
"label": "Flat"
},
{
"dataPropertyID": "PropertyType",
"label": "Cottage"
}
]
};
newJson = new Object();
newJson.filters = new Array();
for (var element in json.filters) {
var check = 0;
for (var element2 in newJson.filters) {
if (json.filters[element].dataPropertyID === newJson.filters[element2].dataPropertyID) {
newJson.filters[element2].label.push(json.filters[element].label);
check = 1;
}
}
if (check == 0) {
var Obj = new Object();
Obj.dataPropertyID = json.filters[element].dataPropertyID;
Obj.label = new Array();
Obj.label.push(json.filters[element].label);
newJson.filters.push(Obj);
}
}
Related
I need to restructure a nested JSON data.
Here is how it looks like:
{
"MainKey1": [
{
"Section1": {
"ParentTag1 Mapped Label": {
"ParentTag1": {
"Tag1 Mapped Label": {
"Tag1": "1234567890"
}
}
}
}
},
{
"Section2": {
"ParentTag1 Mapped Label": {
"ParentTag1": {
"Tag1 Label": {
"Tag1": "111222333444"
},
"Tag2 Label": {
"Tag2": "121212"
},
"Tag3 Label": {
"Tag3": "0987654321"
}
}
}
}
}
],
"MainKey2": [
{
"Section1": {
"ParentTag1 Mapped Label": {
"ParentTag1": {
"Tag1 Mapped Label": {
"Tag1": "1234567890"
}
}
}
}
}
]
}
And this is a sample of the converted JSON:
{
MainKey: [
{
Section1: [
{
ParentTag1: [
{ Tag1: "1234567890" }
]
}
]
},
{
Section2: [
{
ParentTag1: [
{ Tag1: "111222333444" },
{ Tag2: "121212" },
{ Tag3: "0987654321" }
]
}
]
}
],
MainKey2: [
{
Section1: [
{
ParentTag1 : [
{ Tag1: "1234567890" }
]
}
]
}
]
}
Rules:
Everything inside a MainKey (outermost keys, could be any name) should be an array
All labels should be stripped (as the label could be any name, without the actual word "Label", we can determine if it is a label based on the depth level. Since the JSON will have the label as the parent and the actual "tag" as a child.
Here is what I currently have (it is a mess, sorry!)
function convertJson (jsonObj) {
const mainKeys = Object.keys(jsonObj)
let output = {}
for (let i = 0; i < mainKeys.length; i++) {
const mainKey = mainKeys[i]
let result = []
output[mainKey] = result
for (let j = 0; j < jsonObj[mainKey].length; j++) {
const innerObj = {...jsonObj[mainKey][j]}
const sectionName = Object.keys(innerObj)[0]
const sectionObj = {}
sectionObj[sectionName] = []
const index = result.push(sectionObj) - 1
parseObj(innerObj[sectionName], result[index], 0) // if I change 2nd param to: result, it generates incorrect output
}
}
console.log(output)
}
function parseObj (innerObj, result, depthCount) {
for (var key in innerObj) {
if (typeof innerObj[key] === "object") {
if (depthCount % 2 === 1) {
const parentObj = {}
parentObj[key] = []
result.push(parentObj)
depthCount++
parseObj(innerObj[key], parentObj[key], depthCount)
} else {
depthCount++
parseObj(innerObj[key], result, depthCount)
}
} else {
const keyValuePairObj = {}
keyValuePairObj[key] = innerObj[key]
result.push(keyValuePairObj)
}
}
return result
}
convertJson(json)
But it generates an error:
Uncaught TypeError: result.push is not a function
Now if I change line 90 from:
parseObj(innerObj[sectionName], result[index], 0)
to:
parseObj(innerObj[sectionName], result, 0)
Here is incorrect output:
{
"MainKey1": [
{
"Section1": []
},
{
"ParentTag1": [
{
"Tag1": "1234567890"
}
]
},
{
"Section2": []
},
{
"ParentTag1": [
{
"Tag1": "111222333444"
},
{
"Tag2 Label": [
{
"Tag2": "121212"
}
]
},
{
"Tag3": "0987654321"
}
]
}
],
"MainKey2": [
{
"Section1": []
},
{
"Tag1": "1234567890"
}
]
}
And here is my fiddle:
https://jsfiddle.net/kzaiwo/L4avxmyd/36/
Thanks a lot! Appreciate any help!
I have below 3 objects listed below with data.
I want to find const oldData.data.parameter_value = b and oldData.data.label_value = b inside
each object of const newData.selected_parameter_value.
And if value exist in newData array, then replace all newData.selected_parameter_value.parameter_value = b and newData.selected_parameter_value.label_value = b , with const updatedData.data.parameter_value = red and const updatedData.data.label_value = red.
For ex -
const oldData = {
"action": "edit",
"data": {
"parameter_value": "b",
"label_value": "b"
}
};
const updatedData = {
"action": "update",
"data": {
"parameter_value": "red",
"label_value": "red"
}
};
const newData = [
{
"context": [],
"selected_parameter_value": [
{
"label_value": "a",
"parameter_value": "a"
},
{
"label_value": "b",
"parameter_value": "b"
}
]
},
{
"context": [],
"selected_parameter_value": [
{
"label_value": "b",
"parameter_value": "b"
}
]
}
];
Expected Output
const newData = [
{
"context": [],
"selected_parameter_value": [
{
"label_value": "a",
"parameter_value": "a"
},
{
"label_value": "red",
"parameter_value": "red"
}
]
},
{
"context": [],
"selected_parameter_value": [
{
"label_value": "red",
"parameter_value": "red"
}
]
}
];
Can Anyone help me to do this.
i tried below code but i dont know how to update matching objects in newData and keep all objects as it is.
editContextData(data) {
if (data.action === 'edit') {
this.oldData = data;
}
if (data.action === 'update') {
const oldData = this.oldData;
const updatedData = this.newData;
const newData = this.selectedParameterContext.records;
const newSelectedParameterContext = {
'records': []
};
newData.forEach(function (record) {
const newSelectedParameterValues = [];
record.selected_parameter_value.forEach(function (parameter) {
if(parameter.parameter_value === oldData.data.parameter_value && parameter.label_value === oldData.data.label_value){
// here i want to update object and push new values in array.
newSelectedParameterValues.push(updatedData);
}
});
newSelectedParameterContext.records.push({ 'selected_parameter_value': newSelectedParameterValues });
});
console.log(newSelectedParameterContext,"rrr");
this.selectedParameterContext = newSelectedParameterContext;
}
}
newData.forEach((item) => {
item.selected_parameter_value.forEach((obj) => {
if (oldData.data.parameter_value === obj.parameter_value) {
obj.parameter_value = updatedData.data.parameter_value;
}
if (oldData.data.label_value === obj.label_value) {
obj.label_value = updatedData.data.label_value;
}
})
Or if both have to be the same at the same moment then:
newData.forEach((item) => {
item.selected_parameter_value.forEach((obj) => {
if (oldData.data.parameter_value === obj.parameter_value && oldData.data.label_value === obj.label_value) {
obj.parameter_value = updatedData.data.parameter_value;
obj.label_value = updatedData.data.label_value;
}
});
});
I am using DataTables with ajax and I am trying to dynamically generate a columns list as in the example here: https://datatables.net/examples/ajax/orthogonal-data.html (only in my case I have display and order for all items).
I tried with this approach, but this doesn't work and I am guessing push my sub values wrong.
Input (ajax result):
[{
"itemId": {
"order": "BG007002",
"display": "BG007002"
},
"builtDate": {
"order": "2000-03-01",
"display": "01.03.2000"
},
"openedDate": {
"order": "2005-07-09",
"display": "09.07.2005"
},
"buildingSize": {
"order": 15000,
"display": "15.000"
}
}, // ...
Expected output:
[
{ data: {
_: "itemId.display",
sort: "itemId.order"
}
},
{ data: {
_: "builtDate.display",
sort: "builtDate.order"
}
},
{ data: {
_: "openedDate.display",
sort: "openedDate.order"
}
},
{ data: {
_: "buildingSize.display",
sort: "buildingSize.order"
}
}
]
My approach:
var reportColsShort = $('#reportColsShort').text().slice(0,-1);
var aoCols = [];
var colss = reportColsShort.split(',');
for (var i = 0; i < reportColsShort.split(',').length; i++) {
var aoColss = {};
aoColss['data']['_'] = colss[i].display;
aoColss['data']['sort'] = colss[i].order;
aoCols.push(aoColss); // expected output
}
Error:
Cannot set property '_' of undefined.
Update:
Here is one more reference to what I am trying to achieve:
https://datatables.net/reference/option/columns.render#Examples
You can take the ajax result and then use a map see docs to structure your data like this:
const data = [{
"itemId": {
"order": "BG007002",
"display": "BG007002"
},
"builtDate": {
"order": "2000-03-01",
"display": "01.03.2000"
},
"openedDate": {
"order": "2005-07-09",
"display": "09.07.2005"
},
"buildingSize": {
"order": 15000,
"display": "15.000"
}
}];
const mapResult = data.map((elem) => {
let array = [];
Object.keys(elem).forEach((key) => {
const temp = {
data: {
_: elem[key].display,
sort: elem[key].order
}
}
array.push(temp);
});
return array;
});
console.log(mapResult);
I have an array this the format below. Trying to push multiple entire subarrays (starting with A-) fulfilling a condition to a new array and keep the array format. Have no success with the code below.
Array:
{"#VER": {
"A-1": {
"verdatum": "2016-07-08",
"vertext": "1073, Almi",
"trans": [{
"account": "1510",
"amount": "52500.00"
}, {
"account": "3010",
"amount": "-42000.00"
}, {
"account": "2611",
"amount": "-10500.00"
}]
},
"A-2": {
"verdatum": "2016-07-08",
"vertext": "1074, Text",
"trans": [{
"account": "1510",
"amount": "15000.00"
}, {
"account": "3010",
"amount": "-12000.00"
}, {
"account": "2611",
"amount": "-3000.00"
}]
}
}
}
Code so far, but changes format of array
var newarray = [];
$.each(array["#VER"], function(i, item) {
if (condition for subarray) {
newarray.push(i,item);
}
});
You're working with an object here, not an array. This code should work:
var data = { ... }; // your original data object
var filteredData = filterData(data);
function filterData(data) {
var verData = data['#VER'];
var filteredVerData = {};
$.each(verData, function(key, value) {
if(value.vertext === '1073, Almi') { // your condition
filteredVerData[key] = value;
}
});
return {
'#VER': filteredVerData
};
}
But if you have many root keys like '#VER' and you need to filter all of them, you'd need to write one more loop:
var data = { ... }; // your original data object
var filteredData = filterData(data);
function filterData(data) {
var result = {};
$.each(data, function(verKey, verData) {
$.each(verData, function(aKey, aData) {
if(aData.vertext === '1073, Almi') { // your condition
result[verKey] = result[verKey] || {};
result[verKey][aKey] = aData;
}
});
});
return result;
}
I'm trying to loop through some json nodes after finding a specific json node.
So, here's the INPUT:
{
"search": {
"result": {
"DN": {
"$": "A,B,C"
},
"attribute-value": [
{
"#name": "name",
"$": "nameHere"
},
{
"#name": "account",
"$": "accountNameHere"
},
{
"#name": "role",
"$": "roleA"
},
{
"#name": "role",
"$": "roleB"
}
]
}
}}
As you can see there are 2 roles at the end of the json payload above.
So, I get to that #name = role with the following logic:
var attributeValue = node['search'].result['attribute-value'];
for (var i = 0; i < attributeValue.length; i++) {
if (attributeValue[i]['#name'] === 'role') {
var vRole = attributeValue[i].$;
//The newJson.roles.role is to assign it to the new payload below
newJson.roles.role = vRole;
}
}
Once I get there, I'd like to pick up both roleA and roleB and output it into the following newJson payload:
var newJson = {
"newJson": {
"roles": [{
"role": {}
}, {
"role": {}
}],
}
}
The goal is to be able to get all the INPUT role nodes and output it in the newJson payload, but when I attempt to issue a for loop after getting to that #name=role, it fails.
Any suggestion is well appreciated.
Thank you.
I think you should append a new object to the roles array, just like this in your for loop:
var attributeValue = node['search'].result['attribute-value'];
for (var i = 0; i < attributeValue.length; i++) {
if (attributeValue[i]['#name'] === 'role') {
var vRole = attributeValue[i].$;
newJson.roles.push({
role: vRole
});
}
}
Hope this can help
Try this:
var attributeValue = node['search'].result['attribute-value'];
var newJson = {roles:[]};
attributeValue.forEach(function(item){
if(item["#name"]==="role"){
newJson.roles.push({role:item["$"]})
}
});
console.log(JSON.stringify(newJson));
You can use filter and map array methods.
newJson.roles = attributeValue
.filter(function(x){return x['#name']==='role'})
.map(function(x){return {'role': x['$']}})
Thanks everyone - you're all awesome!
This worked out for me:
JSBIN
var d = {
"search": {
"result": {
"DN": {
"$": "A,B,C"
},
"attribute-value": [
{
"#name": "name",
"$": "nameHere"
},
{
"#name": "account",
"$": "accountNameHere"
},
{
"#name": "role",
"$": "roleA"
},
{
"#name": "role",
"$": "roleB"
}
]
}
}};
var newJson = {
"newJson": {
"roles": []
}
};
var attributeValue = d.search.result['attribute-value'];
for (var i = 0; i < attributeValue.length; i++) {
if (attributeValue[i]['#name'] === 'role') {
var vRole = attributeValue[i].$;
newJson.newJson.roles.push({"role": vRole});
}
}
console.log(newJson);
~~~~~~~~~~~~~~~~~~~~~ final result ~~~~~~~~~~~~~~
[object Object] {
newJson: [object Object] {
roles: [[object Object] {
role: "roleA"
}, [object Object] {
role: "roleB"
}]
}
}