Appending to JSON object using JavaScript - javascript

I'm building the JSON object using JavaScript. How would I inset the following data to the bottom of the stack:
"hello": { "label":"Hello", "url":"#hello" }
in to the following variable:
var ListData = {
"main": {
"label":"Main",
"url":"#main"
},
"project": {
"label":"Project",
"url":"#project"
},
"settings": {
"label":"Settings",
"url":"#settings",
"subnav":[
{
"label":"Privacy",
"url":"#privacy"
},
{
"label":"Security",
"url":"#security"
},
{
"label":"Advanced",
"url":"#advanced"
}
]
}
};
So the variable looks like:
var ListData = {
"main": {
"label":"Main",
"url":"#main"
},
"project": {
"label":"Project",
"url":"#project"
},
"settings": {
"label":"Settings",
"url":"#settings",
"subnav":[
{
"label":"Privacy",
"url":"#privacy"
},
{
"label":"Security",
"url":"#security"
},
{
"label":"Advanced",
"url":"#advanced"
}
]
},
"hello": {
"label":"Hello",
"url":"#hello"
}
};
I used the following code but it doesn't seem to work:
var NewData = '"hello": { "label":"Hello", "url":"#hello" }';
ListData.push(NewData);

You can insert it directly with an object literal:
ListData.hello = { label: "Hello", url: "#hello" };

If you are using jQuery, you can use the .extend() jQuery API like:
$.extend(ListData, {"hello": { "label":"Hello", "url":"#hello" }});

I have one more solution using underscore.js module,
var _ = require("underscore");
var src = {
"main": {
"label": "Main",
"url": "#main"
},
"project": {
"label": "Project",
"url": "#project"
},
"settings": {
"label": "Settings",
"url": "#settings",
"subnav": [
{
"label": "Privacy",
"url": "#privacy"
},
{
"label": "Security",
"url": "#security"
},
{
"label": "Advanced",
"url": "#advanced"
}
]
}
};
var dest = {"hello": { "label":"Hello", "url":"#hello" }};
var data = _.extend(src, dest);
console.log(JSON.stringify(data));
Required op :
{"main":{"label":"Main","url":"#main"},"project":{"label":"Project","url":"#project"},"settings":{"label":"Settings","url":"#settings","subnav":[{"label":"Privacy","url":"#privacy"},{"label":"Security","url":"#security"},{"label":"Advanced","url":"#advanced"}]},"hello":{"label":"Hello","url":"#hello"}}

Keeping with you object literal statements just add another object to your ListData object.
ListData.hello = { "label":"Hello", "url":"#hello" };
push is only for Javascript Arrays.

A JavaScript Object Literal is a comma-separated list of name/value pairs wrapped by a pair of curly braces.
To append the property name of encampment name with a value of Valley Forge to the bottom of the stack, simply add the property name after the JSON object with a dot syntax. Then specify the value. (See 'Append data' below)
You can also delete the appended name/value pair from the object literal. (See 'Delete data below')
// Start with some JSON
var myJson = { "name":"George Washington", "rank":"General", "serial":"102" };
// Append data
myJson.encampment = "Valley Forge";
// Delete data
delete myJson.encampment

Related

How to create a json object from another json object using JavaScript?

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)};

How to find and replace value in JSON?

I have an object like this:
{
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
}
I need to find all 'name' keys and replace its value only if it starts with 'test name' then return new JSON object:
{
"responses": {
"firstKey": {
"items": {
"name": "N/A"
}
},
"anotherKey": {
"items": {
"name": "N/A"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
}
The problem is that the keys are not consistent through the objects, i.e. 'firstKey', 'secondKey'... I tried ForEach but it seems to be too cumbersome... So I need either lodash or vanila JavaScript to replace the values.
The javascript object should be iterated and then each value of name can be checked and replaced. There are checks such as hasOwnProperty() that can be used to make sure you are not iterating objects that are missing "items" or "name" for better error handling.
var data = {
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
};
Given the JSON above you can use a simple for statement to iterate and then check each name for some value and replace.
for(var key in data.responses){
if ((data.responses[key].items.name).match(/test name/)){
data.responses[key].items.name = "N/A";
}
}
To check your replacements you can log data to the console.
console.log(JSON.stringify(data));
It can also be done during parsing :
var json = `{
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
}`
var obj = JSON.parse(json, (k, v) => k == 'name' && /^test name/.test(v) ? 'N/A' : v)
console.log( obj )
A javascript object is for all intents and purposes a tree — though it can be, and may well be, a directed graph — that quite possibly may be cyclic meaning a node in the graph points back to own of its own parents. Following a cycle can result in never-ending recursion or loop.
You want to use something like traverse to do what you're talking about. It takes care of all the stuff that makes traversing a graph hassle — dealing with cycles in the graph and the like.
https://www.npmjs.com/package/traverse
https://github.com/substack/js-traverse
const traverse = require('traverse');
. . .
var scrubbed = traverse(obj).map( function(value) {
const isTestName = this.key === 'name'
&& value
&& /^test name/i.test(value)
;
if (isTestName) {
this.update('N/A');
}
});
NOTE: The callback function given to travese can't be an arrow function (() => {...} as that function's this context is the traverse context for the current node being inspected.
That traverse context also gives you access to the entire path from the root down to the current node, along with an upward link to the parent node's traverse context.
Do something like this. Convert to string replace using regex (add key to regex as well) and then convert back.
var data = {
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
};
var originalMsg = JSON.stringify(data);
console.log(data)
console.log(originalMsg)
var updatedMsg = originalMsg.replace(/test name [a-z]*/g, "N/A");
console.log(updatedMsg)
var newObj = JSON.parse(updatedMsg);
console.log(newObj);

How to get the value of a deep nested json object?

I'm working on an app in javascript, and I have this json object (this is a simplified example of the actual json object)
{
"data": [
"user": {
"pictures"{
"sizes"[
0: {
"link": "http://www"
},
1: {
"link": "http://"
}
]
}
}
]
}
And I want to get the value of link, so i tried data.user.pictures.sizes[0].link, and it returned an error. How to get the right value?
edit: I'm using a map function to loop around the data object, so i can display values in an html page. it works for most of the other items, except for pictures sizes, i cant seem to get the value of the second item in the sizes array.
From the data, it shows that 'data' contains array and sizes contains array that contains object of properties 0 and 1 , so do this
data[0].user.pictures.sizes[0].0.link
First of all you need to have colons to "pictures" and "sizes" :)
Secondly, it depends what your structure is.
for example:
if you need to use arrays as they appear in your example:
var a = {
"data": [
{
"user": {
"pictures": {
"sizes": [
{
0: {
"link": "http://www"
}
},
{
1: {
"link": "http://"
}
}
]
}
}
}
]
}
console.log(a.data[0].user.pictures.sizes[0][0].link);
or you just need a json without arrays in it:
var b = {
"data": {
"user": {
"pictures": {
"sizes": {
0: {
"link": "http://www"
},
1: {
"link": "http://"
}
}
}
}
}
}
console.log(b.data.user.pictures.sizes[0].link);
or you can even mix them:
var c = {
"data": {
"user": {
"pictures": {
"sizes": [
{
"link": "http://www"
},
{
"link": "http://"
}
]
}
}
}
}
console.log(c.data.user.pictures.sizes[0].link);
notice the subtle difference of "sizes" in b and c and the double array of a. This is because json with index as keys is the same as an array. check this example:
var example = [
{
0: "example00",
1: "example01",
2: "example02"
},
{
0: "example10",
1: "example11",
2: "example12"
},
]
console.log(example[0][1]); // == example01
you can see that you have 2 arrays within the example array
hope that helps :)
Your JSON is wrong, it should be as below :
var js = {
"data": {
"user":{
"pictures":{
"sizes":[
{
"link":"http://www"
},
{
"link":"http://"
}
]
}
}
}
}
To get the value:
js.data.user.pictures.sizes[0].link

Javascript how to return array from map

I have the following Json
var myjson = [{
"files": [
{
"domain": "d",
"units": [
{
"key": "key1",
"type": "2"
},
{
"key": "key2",
"type": "2"
},
{
"key": "key3",
"type": "2"
}]
},
{
"domain": "d1",
"units": [
{
"key": "key11",
"type": "2"
},
{
"key": "key12",
"type": "2"
},
{
"key": "key13",
"type": "2"
}]
}]
},
{
"files": [
{
"domain": "d",
"units": [
{
......
I want to create an new array from this Json array. The length of array will be the number of "units" in this Json object.
So I need to extract "units" and add some data from parent objects.
units: [{
domain: "",
type: "",
key: ""
}, {
domain: "",
type: "",
key: ""
},
{
domain: "",
type: "",
key: ""
}
....
];
I guess i can probably do something like this:
var res = [];
myjson.forEach(function(row) {
row.files.forEach(function(tfile) {
tfile.units.forEach(function(unit) {
var testEntity = {
domain: tfile.domain,
type : unit.type,
key: unit.key
};
res.push(testEntity);
});
});
});
But it is difficult to read and looks not so good. I was thinking to do something like :
var RESULT = myjson.map(function(row) {
return row.files.map(function(tfile) {
return tfile.units.map(function(unit) {
return {
domain: tfile.domain,
type : unit.type,
key: unit.key
};
});
});
});
But This doesn't work and looks not better . Is there any way to do so it works, maybe in more declarative way. hoped Ramda.js could help.
It there any good approach in general to get data from any Nested json in readable way?
Implementing something like:
nestedjson.findAllOnLastlevel(function(item){
return {
key : item.key,
type: type.key,
domain : item.parent.domain}
});
Or somehow flatten this json so all properties from all parents object are moved to leafs children. myjson.flatten("files.units")
jsbin http://jsbin.com/hiqatutino/edit?css,js,console
Many thanks
The function you can use here is Ramda's R.chain function rather than R.map. You can think of R.chain as a way of mapping over a list with a function that returns another list and then flattens the resulting list of lists together.
// get a list of all files
const listOfFiles =
R.chain(R.prop('files'), myjson)
// a function that we can use to add the domain to each unit
const unitsWithDomain =
(domain, units) => R.map(R.assoc('domain', domain), units)
// take the list of files and add the domain to each of its units
const result =
R.chain(file => unitsWithDomain(file.domain, file.units), listOfFiles)
If you wanted to take it a step further then you could also use R.pipeK which helps with composing functions together which behave like R.chain between each of the given functions.
// this creates a function that accepts the `myjson` list
// then passes the list of files to the second function
// returning the list of units for each file with the domain attached
const process = pipeK(prop('files'),
f => map(assoc('domain', f.domain), f.units))
// giving the `myjson` object produces the same result as above
process(myjson)
Pure JS is very sufficient to produce the result in simple one liners. I wouldn't touch any library just for this job. I have two ways to do it here. First one is a chain of reduce.reduce.map and second one is a chain of reduce.map.map. Here is the code;
var myjson = [{"files":[{"domain":"d","units":[{"key":"key1","type":"2"},{"key":"key2","type":"2"},{"key":"key3","type":"2"}]},{"domain":"d1","units":[{"key":"key11","type":"2"},{"key":"key12","type":"2"},{"key":"key13","type":"2"}]}]},{"files":[{"domain":"e","units":[{"key":"key1","type":"2"},{"key":"key2","type":"2"},{"key":"key3","type":"2"}]},{"domain":"e1","units":[{"key":"key11","type":"2"},{"key":"key12","type":"2"},{"key":"key13","type":"2"}]}]}],
units = myjson.reduce((p,c) => c.files.reduce((f,s) => f.concat(s.units.map(e => (e.domain = s.domain,e))) ,p) ,[]);
units2 = myjson.reduce((p,c) => p.concat(...c.files.map(f => f.units.map(e => (e.domain = f.domain,e)))) ,[]);
console.log(units);
console.log(units2);
For ES5 compatibility i would suggest the reduce.reduce.map chain since there is no need for a spread operator. And replace the arrow functions with their conventional counterparts like the one below;
var myjson = [{"files":[{"domain":"d","units":[{"key":"key1","type":"2"},{"key":"key2","type":"2"},{"key":"key3","type":"2"}]},{"domain":"d1","units":[{"key":"key11","type":"2"},{"key":"key12","type":"2"},{"key":"key13","type":"2"}]}]},{"files":[{"domain":"e","units":[{"key":"key1","type":"2"},{"key":"key2","type":"2"},{"key":"key3","type":"2"}]},{"domain":"e1","units":[{"key":"key11","type":"2"},{"key":"key12","type":"2"},{"key":"key13","type":"2"}]}]}],
units = myjson.reduce(function(p,c) {
return c.files.reduce(function(f,s) {
return f.concat(s.units.map(function(e){
e.domain = s.domain;
return e;
}));
},p);
},[]);
console.log(units);
Something like this should work. .reduce is a good one for these kind of situations.
const allUnits = myjson.reduce((acc, anonObj) => {
const units = anonObj.files.map(fileObj => {
return fileObj.units.map(unit => {
return {...unit, domain: fileObj.domain})
})
return [...acc, ...units]
}, [])
Note that this relies on both array spreading and object spreading, which are ES6 features not supported by every platform.
If you can't use ES6, here is an ES5 implementation. Not as pretty, but does the same thing:
var allUnits = myjson.reduce(function (acc, anonObj) {
const units = anonObj.files.map(function(fileObj) {
// for each fileObject, return an array of processed unit objects
// with domain property added from fileObj
return fileObj.units.map(function(unit) {
return {
key: unit.key,
type: unit.type,
domain: fileObj.domain
}
})
})
// for each file array, add unit objects from that array to accumulator array
return acc.concat(units)
}, [])
Try this
var myjson = [{
"files": [{
"domain": "d",
"units": [{
"key": "key1",
"type": "2"
}, {
"key": "key2",
"type": "2"
}, {
"key": "key3",
"type": "2"
}]
},
{
"domain": "d1",
"units": [{
"key": "key11",
"type": "2"
}, {
"key": "key12",
"type": "2"
}, {
"key": "key13",
"type": "2"
}]
}
]
}];
//first filter out properties exluding units
var result = [];
myjson.forEach(function(obj){
obj.files.forEach(function(obj2){
result = result.concat(obj2.units.map(function(unit){
unit.domain = obj2.domain;
return unit;
}));
});
});
console.log(result);

javascript and json

I'm using javascript with a json library and running into a little trouble. Here's my json output:
{
"artist": {
"username": "myname",
"password": "password",
"portfolioName": "My Portfolio",
"birthday": "2010-07-12 17:24:36.104 EDT",
"firstName": "John",
"lastName": "Smith",
"receiveJunkMail": true,
"portfolios": [{
"entry": [{
"string": "Photos",
"utils.Portfolio": {
"name": "Photos",
"pics": [""]
}
},
{
"string": "Paintings",
"utils.Portfolio": {
"name": "Paintings",
"pics": [""]
}
}]
}]
}
}
In javascript I'm trying to access the entries in the map like so:
var portfolios = jsonObject.artist.portfolios.entry;
var portfolioCount = portfolios.length;
for ( var index = 0; index < portfolioCount; index++ )
{
var portfolio = portfolios[index];
txt=document.createTextNode("Portfolio Name: " + portfolio['string'] );
div = document.createElement("p");
div.appendChild ( txt );
console.appendChild(div);
}
but portfolios is "undefined". What's the correct way to do this?
Look at your JSON results. portfolios is a one-element array; portfolios[0] is an object containing a single key, entry, which maps to an array of two objects that have both string and utils.Portfolio keys. Thus, the syntax jsonObject.artist.portfolios.entry will not work. Instead, you want jsonObject.artist.portfolios[0].entry.
If possible, I would suggest changing whatever code generates those JSON results to remove the entry level of indirection entirely, e.g. like so:
{
"artist": {
/* ... */
"portfolios": [
{
"string": "Photos",
"utils.Portfolio": {
"name": "Photos",
"pics": [""]
}
},
{
"string": "Paintings",
"utils.Portfolio": {
"name": "Paintings",
"pics": [""]
}
}
]
}
}
Then you could access it with
var portfolios = jsonObject.artist.portfolios;
for (var i = 0, portfolio; portfolio = portfolios[i]; ++i)
{
// use portfolio variable here.
}
There is an array in your object. I believe you're looking for this:
var portfolios = jsonObject.artist.portfolios[0].entry;
The portfolios property is an array, so you need to use an index to get the first element:
var portfolios = jsonObject.artist.portfolios[0].entry;

Categories

Resources