js loop after a certain json node - javascript

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"
}]
}
}

Related

add elements from array into existing json object

Is there a similar method to array.push that one can use to inject a new node into a json object?
I have an endpoint that requires a payload with dynamic element names based on what is being passed in, so i need to scrape the array and insert it into the payload for the correct format.
Example of the end-result payload i need:
{
"fields": {
"project": {
"key": projectKey
},
"summary": summary,
"description": description,
"issuetype": {
"name": issueType
},
"customfield_123456": "value1",
"customfield_7890": "value2"
}
}
This is the function in the controller that consumes the request body and attempts to inject the values in the customFields Array as elements in the json object but is not working:
const createIssueApi = async(req, res, next) => {
try {
let {
projectKey,
summary,
description,
issueType,
customFields
} = req.body;
console.log(req.body)
let jiraIssue = {
"fields": {
"project": {
"key": projectKey
},
"summary": summary,
"description": description,
"issuetype": {
"name": issueType
}
}
}
for (let ix = 0; ix < customFields.length; ix++) {
jiraIssue.fields[$ {
customFields[ix]
}] = customFields[ix];
}
console.log("Jira Issue payload: ", jiraIssue)
} catch (e) {
console.log(e)
}
}
This is the payload being sent in:
{
"projectKey": "JK",
"summary": "summary text",
"description": "THIS IS JUST A TEST",
"issueType": "Submit a request or incident",
"customFields": [{
"customfield_123456": "value1"
},
{
"customfield_7890": "value2"
}
]
}
there are methods
Array.prototype.push()
Array.prototype.pop()
Array.prototype.shift()
Array.prototype.unshift()
Array.prototype.concat()
for instance
const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count);
// expected output: 4
console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows"]
animals.push('chickens', 'cats', 'dogs');
console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]
You appear to be attempting to use the same value for both the name and the value, and your Js seems to be invalid in that spot - [$ { is not valid js, but something like this should work
jiraIssue.fields[`customFields_${ix}`] = customFields[ix];
You can try using for...of and Object.entries inside for
const customFields = [{
'customfield_123456': 'value1'
},
{
'customfield_7890': 'value2'
}
];
const jiraIssue = {'fields': {}};
for (let ix = 0; ix < customFields.length; ix++) {
for (const [key, val] of Object.entries(customFields[ix])) {
jiraIssue.fields[key] = val;
}
}
console.log(jiraIssue);
The following is an example used with reduce
const restructure = (req) => {
const {customFields, ...rest} = req.body;
const fields = {
'project': {
"key": rest['projectKey']
},
'summary': rest['summary'],
'description': rest['description'],
'issuetype': {
"name": rest['issueType']
}
};
customFields.reduce((accumu, current) => {
for (const [key, val] of Object.entries(current)) {
accumu[key] = val;
}
return accumu;
}, fields);
return {fields};
}
const req = {
"body": {
"projectKey": "JK",
"summary": "summary text",
"description": "THIS IS JUST A TEST",
"issueType": "Submit a request or incident",
"customFields": [{
"customfield_123456": "value1"
},
{
"customfield_7890": "value2"
}
]
}
};
console.log(restructure(req));

Function to build a line to retrieve data from json

I'm writing a function that takes arguments and add them to form a line to look for data in a JSON file. I've defined a variable for the readFileSync and the add to it the arguments of the function to look for the data.
var jf = require('jsonfile'),
file = 'logins.json',
i = 1;
var jsonData = jf.readFileSync(file);
function getJSONData() {
var n = 1;
var com = '';
do {
if (arguments[n] !== undefined) {
com += `['${arguments[n]}']`;
}
n++;
} while (n < arguments.length);
return com;
}
var h = getJSONData(i, 'operator', 'id');
console.log(jsonData[i] + h);
This is my JSON:
[
{
"operator": {
"id": "avalle",
"pass": "Aa123456",
"something": "idk",
"account": [
{
"type": "asd",
"idk": "asd"
},
{
"type": "asd",
"idk": "asd"
}
]
}
},
{
"operator": {
"id": "oleal",
"pass": "Aa123456",
"something": "idk",
"account": [
{
"type": "asd",
"idk": "asd"
},
{
"type": "asd",
"idk": "asd"
}
]
}
}
]
I should get a line of jsonData[i]['param1']['param2'] that locates the data in the file.
Instead i get undefined or [object Object]['operador']['id']
If you want a property to be returned from the function you can make this change:
function getJSONData(jsonData) {
var n = 1;
var result = jsonData;
do {
if (result[arguments[n]]) {
result = result[arguments[n]]
} else {
console.error(`Property ${arguments[n]} does not exist on obj:`, result)
}
n++;
} while (n < arguments.length);
return result;
}
var h = getJSONData(jsonData[i], 'operator', 'id');
Otherwise you return a string from getJSONData that looks like "[prop1][prop2]" and it will not retrieve a property by trying to concat Object + string

How to convert Json into associative array or key value array

I have following Json which i need to insert into a table.
I want to convert each student detail into a row.
Because if i loop through the rows as per the existing structure i am reading one column as a row.
var json {
"Students":[
{
"name":{
"value":"Allan"
},
"number":{
"value":"123"
}
},
{
"name":{
"value":"Frank"
},
"number":{
"value":"456"
}
}
]
}
Ideally i want to the above as
{ "name": "Allan", "number": 123};
{ "name": "Frank", "number": 456};
I am looping through the Json as below
var objectKeys = Object.keys(json);
for (var key in objectKeys)
{
var student = json.Students;
for (var i = 0; i < student .length; i++) {
for (var column in json.Students[i]) {
window.print(column);
window.print(json.Students[i][column].value);
}
}
}
NOTE: No JQuery, want to achieve the above through normal Javascript.
If you want to transform the data, you can use Array.map
var json = {"Students":[{"name":{"value":"Allan"},"number":{"value":"123"}},{"name":{"value":"Frank"},"number":{"value":"456"}}]};
let result = json.Students.map(o => ({
name: o.name.value,
number: o.number.value
}));
console.log(result);
If you want to access the data, you can use Array.forEach
var json = {"Students":[{"name":{"value":"Allan"},"number":{"value":"123"}},{"name":{"value":"Frank"},"number":{"value":"456"}}]};
json.Students.forEach(o => console.log({name: o.name.value, number: o.number.value}));
var json = {
"Students":[
{
"name":{
"value":"Allan"
},
"number":{
"value":"123"
}
},
{
"name":{
"value":"Frank"
},
"number":{
"value":"456"
}
}
]
}
var studentData = JSON.stringify(json.Students);
var convertedData = JSON.parse(studentData.replace(/\{\"value\"\:/g,"").replace(/\}\,\"number/g,',"number').replace(/\"\}\}/g,'"}'));
Try this :)
No map or reduce. Just classic Javascript.
var json = {
"Students": [{
"name": {
"value": "Allan"
},
"number": {
"value": "123"
}
},
{
"name": {
"value": "Frank"
},
"number": {
"value": "456"
}
}
]
};
for (var student of json["Students"]) {
console.log(student); //your logic goes here.
}

how to add an element inside a json array at the specific index in a repeating block?

I am trying to add element "delete:true" after each occurrence of "_rev " mentioned in the below sample request.
Original Request:
{
"docs": [
{
"_id": "123",
"_rev": "1-7836",
},
{
"_id": "456",
"_rev": "1-1192",
}
]
}
Expected Request:
{
"docs": [
{
"_id": "123",
"_rev": "1-7836",
"_deleted" :true
},
{
"_id": "456",
"_rev": "1-1192",
"_deleted" :true
}
]
}
When I tried the below code,the ""_deleted" :true" is getting inserted after the -rev element is closed. PFB for the same and suggest.
function main(params) {
for (var i = 0; i< params.docs.length; i++) {
for (var value in params.docs[i]) {
if(value == '_rev' && params.docs[i]._rev ){
var string1 = JSON.stringify(params.docs[i]);
var str = ',';
var string2 = '"';
var string3 =str+string2+ '_deleted'+ string2+ ':' + "true" ;
var res = string1 + string3 ;
}
}
}
}
######################
[
"2018-01-23T09:44:23.568738362Z stdout:
{\"_id\":\"123\",
\"_rev\":\"1-7836\"},
\"_deleted\":true"]
Use map and Object.assign instead of generating a string
var output = params.docs.map( s => Object.assign( {}, {"_deleted" :true}, s ) );
You can then convert this to string using JSON.stringify( output );
Demo
var params = {
"docs": [{
"_id": "123",
"_rev": "1-7836",
},
{
"_id": "456",
"_rev": "1-1192",
}
]
};
var output = params.docs.map(s => Object.assign({}, {
"_deleted": true
}, s));
console.log(output);
var data = {
"docs": [
{
"_id": "123",
"_rev": "1-7836",
},
{
"_id": "456",
"_rev": "1-1192",
}
]
}
var newData = data['docs'].map(item => {
item._delete = true
return item
})
console.log(newData);
Why don't you simply put ._deleted attribute to doc, like this ?
function main(params) {
for (var i = 0; i< params.docs.length; i++) {
params.docs[i]._deleted = true;
var res = JSON.stringify(params.docs[i]);
}
}
}
Or like this :
function main(params) {
for (var i = 0; i< params.docs.length; i++) {
params.docs[i]["_deleted"] = true;
var res = JSON.stringify(params.docs[i]);
}
}
}
You can reference the not existing attribute directly and assign an value:
#!/usr/bin/js
var myJSON = { "docs": [ { "_id":"123", "_rev":"1-200" } ] }
console.log(myJSON);
myJSON.docs[0]["_deleted"]=true;
console.log(myJSON);
Output of example:
# js append.js
{ docs: [ { _id: '123', _rev: '1-200' } ] }
{ docs: [ { _id: '123', _rev: '1-200', _deleted: true } ] }
Read the more extensive example here: Add new attribute (element) to JSON object using JavaScript
So this might be a duplicate ...

Transform JSON Object in AngularJs

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

Categories