Related
I am really junior with JavaScript and json, so I have this JSON input, and I need to get all that information in the "properties" object to create a new JSON object with just that information.
I'm using a base code like this one, but this is just returning {}.
exports.step = function(input, fileInput) {
var alert = {
'Properties': input.alert.properties
}
return JSON.stringify(alert, undefined, 1);
};
Original JSON:
"value": {
"id": "12345",
"entity": {
"_integrationDefinitionId": "7a6764",
"_integrationName": "Apple Main",
"_beginOn": "2021-09-01T02:20:06.189Z",
"displayName": "apple-onev",
"_accountIdPartitioned": "12345|12",
"_class": [
"Deployment",
"Group"
],
"_version": 3,
"_integrationClass": [
"CiSSP",
"Infrastructure"
],
"_accountId": "123456",
"_id": "1e234567",
"_key": "arn:aws:autoscaling:us-west-2:83712398:autoScalingGroup:asd1238-20c8-41aa-bcec-12340912341:autoScalingGroupName/awseb-e-juancito-stack-AWSEBAutoScalingGroup-123456",
"_type": [
"aws_autoscaling_group"
],
"_deleted": false,
"_rawDataHashes": "1233456==",
"_integrationInstanceId": "54321",
"_integrationType": "aws",
"_source": "integration",
"_createdOn": "2021-07-19T23:19:19.758Z"
},
"properties": {
"webLink": "https://google.com",
"arn": "name",
"region": "us-west-2",
"name": "JonnyAndTheVibes",
"launchConfigurationName": "OtherName",
"minSize": 1,
"maxSize": 4,
"desiredCapacity": 1,
"defaultCooldown": 360,
"availabilityZones": "us-west-2a",
"LoadBalancerNames": "MoreInfo",
"healthCheckType": "EC2",
"healthCheckGracePeriod": 0,
"instanceIds": "InstanceName",
"subnetIds": "subnet",
"terminationPolicies": "Default",
"newInstancesProtectedFromScaleIn": false,
"serviceLinkedRoleARN": "aMoreInfo",
"tag.Name": "atag",
"tag.application": "othertag",
"tag.aws:cloudformation:logical-id": "moretagsp",
"tag.aws:cloudformation:stack-id": "taggigante",
"tag.aws:cloudformation:stack-name": "ydaleconlostags",
"tag.elasticbeanstalk:environment-id": "seguimosmetiendoletags",
"tag.elasticbeanstalk:environment-name": "tag",
"tag.env": "tag",
"tag.team": "tag",
"accountId": "tag",
"tag.AccountName": "tag",
"tag.Production": true,
"#tag.Production": ""
}
}
I'm sure that it will be a simple solution.
You appear to be trying to grab properties from the wrong object. It should be value not alert.
const json = '{"value":{"id":"12345","entity":{"_integrationDefinitionId":"7a6764","_integrationName":"Apple Main","_beginOn":"2021-09-01T02:20:06.189Z","displayName":"apple-onev","_accountIdPartitioned":"12345|12","_class":["Deployment","Group"],"_version":3,"_integrationClass":["CiSSP","Infrastructure"],"_accountId":"123456","_id":"1e234567","_key":"arn:aws:autoscaling:us-west-2:83712398:autoScalingGroup:asd1238-20c8-41aa-bcec-12340912341:autoScalingGroupName/awseb-e-juancito-stack-AWSEBAutoScalingGroup-123456","_type":["aws_autoscaling_group"],"_deleted":false,"_rawDataHashes":"1233456==","_integrationInstanceId":"54321","_integrationType":"aws","_source":"integration","_createdOn":"2021-07-19T23:19:19.758Z"},"properties":{"webLink":"https://google.com","arn":"name","region":"us-west-2","name":"JonnyAndTheVibes","launchConfigurationName":"OtherName","minSize":1,"maxSize":4,"desiredCapacity":1,"defaultCooldown":360,"availabilityZones":"us-west-2a","LoadBalancerNames":"MoreInfo","healthCheckType":"EC2","healthCheckGracePeriod":0,"instanceIds":"InstanceName","subnetIds":"subnet","terminationPolicies":"Default","newInstancesProtectedFromScaleIn":false,"serviceLinkedRoleARN":"aMoreInfo","tag.Name":"atag","tag.application":"othertag","tag.aws:cloudformation:logical-id":"moretagsp","tag.aws:cloudformation:stack-id":"taggigante","tag.aws:cloudformation:stack-name":"ydaleconlostags","tag.elasticbeanstalk:environment-id":"seguimosmetiendoletags","tag.elasticbeanstalk:environment-name":"tag","tag.env":"tag","tag.team":"tag","accountId":"tag","tag.AccountName":"tag","tag.Production":true,"#tag.Production":""}}}';
function getAlert(dsta) {
// Destructure the properties object from the
// data's value property
const { properties } = data.value;
// Create a new object with it
const alert = { properties };
// Return the string
return JSON.stringify(alert, null, 2);
};
// Parse the JSON
const data = JSON.parse(json);
// Call the function with the parsed data
const alert = getAlert(data);
console.log(alert);
Additional information
Destructuring assignment
use this function :
function assignJsons(...jsons) {
const convertToObject = jsons.map(json => {
return JSON.parse(json)
});
return JSON.stringify(Object.assign(...convertToObject))
}
//test
console.log(assignJsons(`{"name" : "alex", "family" : "mask"}`, `{"family" : "rejest"}`))
if you want a completely new object
var newJsonObject = JSON.parse('{ "properties":'
+ JSON.stringify (origJson.value.properties) + "}");
or
var newJsonObject={"properties":Object.assign ({}, origJson.value.properties)};
I have an object like the following:
{
"_attrib": {
"PieChart": "T",
"ProductSettings": "true"
},
"WATER": {
"_attrib": {
"Step": "5",
"ProgressAdjust": "41",
}
},
"TEMP": {
"_attrib": {
"Argument": "F7",
"Default": "00"
},
"ITEM": [
{
"_attrib": {
"Name": "Low",
}
},
{
"_attrib": {
"Name": "Normal",
}
},
{
"_attrib": {
"Name": "High",
}
}
]
}
}
what I need to parse is to find where ProgressAdjust is set and then add the name in this case WATER into an array,
I have the following code however the array has all the names (i.e: _attrib, water, temp).
export const productCustomizationOptions = (product: any) => {
const options = [];
Object.entries(product.product).forEach((item1, index1) => {
Object.values(item1[1]).forEach((item2) => {
if (item2.ProgressAdjust !== 'undefined') {
options.push(item1[0]);
}
});
});
console.log('customization options: ', options);
};
any help would be appreciated.
Using Object.entries convert the object into an array of key/value pairs
Filter this array using Array#filter and Optional Chaining (?.)
The optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.
Finally using Array#map extract out only the keys
const
obj = {_attrib:{PieChart:"T",ProductSettings:"true"},WATER:{_attrib:{Step:"5",ProgressAdjust:"41"}},TEMP:{_attrib:{Argument:"F7",Default:"00"},ITEM:[{_attrib:{Name:"Low"}},{_attrib:{Name:"Normal"}},{_attrib:{Name:"High"}}]}},
res = Object.entries(obj).filter(([, o]) => o?._attrib?.ProgressAdjust).map(([k]) => k)
console.log(res)
I have json :
{
"fullName": "abc",
"age": 19,
...
}
I want use Nodejs to add element in above json to object named Variables in below json
{
"variables": {
"fullName" : {
"value" : "abc",
"type" : "String"
},
"age": {
"value" : 19,
"type": "Number"
},
...
}
}
Please help me this case!
You can use Object.entries with .reduce()
let data = {
"fullName": "abc",
"age": 19,
}
let result = Object.entries(data).reduce((a, [key, value]) => {
a.variables[key] = { value, type: typeof value}
return a;
}, { variables: {}})
console.log(result);
We can first entries of that object and then map it accordingly after that we convert that object using Object.fromentries. Here is an implementation:
const obj = { "fullName": "abc", "age": 19 };
const result = Object.fromEntries(Object.entries(obj).map(([k,value])=>[k,{value, type:typeof value}]));
console.log({variable:result});
Are you looking for JSON.parse to get a struct from your file, then JSON.stringify to create a json from your struct ?
I have this JSON object, it's a dynamically generated object, I can't control how it's formatted to json. The problem is that the json looks like this:
{
"id": "def",
"name": "def",
"description": {},
"description.shortened": "def",
"description.extended": "def",
"type": "EDIBLE_BOUQUET",
"image": {},
"image.name": "def",
"image.slug": "def",
"image.extension": "PNG",
"state": "FEATURED",
"stock": "def"
}
How would I go about transforming it into:
{
"id": "def",
"name": "def",
"description": {
"shortened": "def",
"extended": "def"
},
"type": "EDIBLE_BOUQUET",
"image": {
"name": "def",
"slug": "def",
"extension": "PNG"
},
"state": "FEATURED",
"stock": "def"
}
let obj = {
"id": "def",
"name": "def",
"description": {},
"description.shortened": "def",
"description.extended": "def",
"type": "EDIBLE_BOUQUET",
"image": {},
"image.name": "def",
"image.slug": "def",
"image.extension": "PNG",
"state": "FEATURED",
"stock": "def"
}
const transformObj = obj => {
return Object.keys(obj).reduce((acc, key) => {
if(key.indexOf('.') >= 0){
const [parentKey, childKey] = key.split('.');
acc[parentKey] = acc[parentKey] || {};
acc[parentKey][childKey] = obj[key];
} else {
acc[key] = obj[key];
}
return acc;
}, {});
}
console.log(transformObj(obj));
Iterate through the keys of object, and transform it.
function transform(obj){
let tmp={}
Object.keys(obj).forEach(k=>{
if(k.includes('.')){
let path=k.split('.')
let x=path.pop()
path.reduce((cur,p)=>{
if(!(p in cur))cur[p]={}
return cur[p]
},tmp)[x]=obj[k]
}
else{
tmp[k]=obj[k]
}
})
return tmp
}
const obj={
a: 1,
'b.c.d': 2
}
console.log(transform(obj)) // {a: 1, b: {c: {d: 2}}}
If you're in for using lodash, _.set does exactly what you're trying to do here:
const source = {"id":"def","name":"def","description":{},"description.shortened":"def","description.extended":"def","type":"EDIBLE_BOUQUET","image":{},"image.name":"def","image.slug":"def","image.extension":"PNG","state":"FEATURED","stock":"def"};
let target = {};
Object.keys(source).forEach(key => {
_.set(target, key, source[key]);
});
console.log(target);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Just one catch, the parent property should always be before the child properties in your source object, i.e. description should occur before description.shortened.
Fairly straight forward.
Check each property to see if the name contains a ., add the correct property and delete the original.
const src = {
"id": "def",
"name": "def",
"description": {},
"description.shortened": "def",
"description.extended": "def",
"type": "EDIBLE_BOUQUET",
"image": {},
"image.name": "def",
"image.slug": "def",
"image.extension": "PNG",
"state": "FEATURED",
"stock": "def"
};
for (var k in src) {
let index = k.indexOf('.');
if (index > 0){
let [base, prop] = k.split('.');
let value = src[k];
delete src[k]
src[base][prop] = value;
}
}
console.log(src)
Using lodash's set method would be the easiest path.
const json = '{"id": "def","name": "def","description": {},"description.shortened": "def","description.extended": "def","type": "EDIBLE_BOUQUET","image": {},"image.name": "def","image.slug": "def","image.extension": "PNG","state": "FEATURED","stock": "def"}';
const obj = JSON.parse(json);
const newObj = Object.keys(obj).reduce((o, k) => _.set(o, k, obj[k]), {});
console.log(newObj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.5/lodash.min.js"></script>
A concern should be noted that if the object keys are not guaranteed to be in the order shown, some data may be lost. See the following example.
const json = '{"id": "def","name": "def","description.shortened": "def","description.extended": "def","description": {},"type": "EDIBLE_BOUQUET","image": {},"image.name": "def","image.slug": "def","image.extension": "PNG","state": "FEATURED","stock": "def"}';
const obj = JSON.parse(json);
const newObj = Object.keys(obj).reduce((o, k) => _.set(o, k, obj[k]), {});
console.log(newObj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.5/lodash.min.js"></script>
Since the set method iterates over the keys in the order provided from the keys method, the last key will set the value to whatever is provided. So, if the description: {} pair follows any previous description.x: y pair then those values will be lost once the empty object is assigned.
A simple fix would be to include a sort to force the empty object pair to be the first key provided. Note however this will also cause the rest of the object to no longer be in the same order as the original.
const json = '{"id": "def","name": "def","description.shortened": "def","description.extended": "def","description": {},"type": "EDIBLE_BOUQUET","image": {},"image.name": "def","image.slug": "def","image.extension": "PNG","state": "FEATURED","stock": "def"}';
const obj = JSON.parse(json);
const newObj = Object.keys(obj).sort().reduce((o, k) => _.set(o, k, obj[k]), {});
console.log(newObj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.5/lodash.min.js"></script>
If you do need to roll your own then something like the following would suffice:
const json = '{"id": "def","name": "def","description.shortened": "def","description.extended": "def","description": {},"type": "EDIBLE_BOUQUET","image": {},"image.name": "def","image.slug": "def","image.extension": "PNG","state": "FEATURED","stock": "def"}';
const obj = JSON.parse(json);
const newObj = Object.keys(obj).sort().reduce((o, k) => {
const paths = k.split('.');
// Get to currently defined depth of object
let depth = 0;
let oRef = o;
while (oRef.hasOwnProperty(paths[depth])) {
oRef = oRef[paths[depth++]];
}
const val = paths.slice(depth).reduceRight((v, p) => ({[p]: v}), obj[k]);
Object.assign(oRef, val);
return o;
}, {});
console.log(newObj);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.5/lodash.min.js"></script>
I want to hide _id to display on UI using ng-model , I see alot of examples of filtering data using ng-repeat but i did not find angular solution to achieve this task using ng-model.How can hide _id property to display ?
main.html
<div ng-jsoneditor="onLoad" ng-model="obj.data" options="obj.options" ></div>
Ctrl.js
$scope.obj.data = {
"_id": "58a3322bac70c63254ba2a9c",
"name": "MailClass",
"id": "MailTask_1",
"createdBy": "tyuru",
"__v": 0,
"properties": [{
"label": "Java Package Name",
"type": "String",
"editable": true,
"binding": {
"type": "property",
"name": "camunda:class"
},
"$$hashKey": "object:29"
}],
"appliesTo": [
"bpmn:ServiceTask"
]
}
var json = {};
function loadCurrentUserAndTemplate() {
AuthService.getCurrentUser()
.then(function(resp) {
$scope.currentUser = resp.data.id;
// console.log($scope.currentUser);
userTemplate($scope.currentUser);
});
}
loadCurrentUserAndTemplate();
$scope.obj = {
data: json,
options: {
mode: 'tree'
}
};
var privateFields = removePrivateFields($scope.obj.data, ['_id', '__v']);
// add private fields back to $scope.obj.data before POST
var modifiedData = Object.assign({}, $scope.obj.data, privateFields);
function removePrivateFields(obj, props) {
var output = {};
props.forEach(function(prop) {
if (obj.hasOwnProperty(prop)) {
output[prop] = obj[prop];
delete obj[prop];
}
});
return output;
}
function userTemplate(user) {
// console.log('inside template',$scope.currentUser);
templateService.getUserTemplates(user)
.then(function(response) {
// console.log('userTemplate',response.data);
// console.log(response.data.length);
$scope.displayedTemplates = response.data;
if (response.data.length !== 0 && response.data !== null) {
$scope.obj.data = response.data[0];
}
}
you can create a function like removePrivateFields to strip the private fields from original object and attach them back to the modified object before submitting to server
// for testing
var $scope = { obj: {} };
var jsonData = {
"_id": "58a3322bac70c63254ba2a9c",
"name": "MailClass",
"id": "MailTask_1",
"createdBy": "tyuru",
"__v": 0,
"properties": [{
"label": "Java Package Name",
"type": "String",
"editable": true,
"binding": {
"type": "property",
"name": "camunda:class"
},
"$$hashKey": "object:29"
}],
"appliesTo": [
"bpmn:ServiceTask"
]
};
var privateFields = removePrivateFields(jsonData, ['_id', '__v']);
// private fields got removed form actual jsonData
$scope.obj.data = jsonData;
console.log($scope.obj.data);
// once edit
// add private fields back to $scope.obj.data before POST
var modifiedData = Object.assign({}, $scope.obj.data, privateFields);
console.log(modifiedData);
function removePrivateFields(obj, props) {
var output = {};
props.forEach(function(prop) {
if (obj.hasOwnProperty(prop)) {
output[prop] = obj[prop];
delete obj[prop];
}
});
return output;
}
It would be both more performant and along Angular best practices to instead delegate this functionality into your controller or the service fetching the object.
Ideally, you want to perform any object manipulation or formatting within an Angular service, but you could also do it within your controller (probably fine if you're just instantiating your JSON editor with mock data).