Function to build a line to retrieve data from json - javascript

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

Related

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 array of strings into custom structure

I need to convert this array of strings into a special structure
https://github.com/jonmiles/bootstrap-treeview
This is my Input String array:
******************
"productone"
"productone\level2\level3"
"productwo"
"productwo\level2\level3\level4"
"productwo\level2\level3.1\level4\level5"
"productwo\level2\level3.2\level4\level5"
so can you imagine this:
"memory"
"memory\ram"
"memory\ram\ddr\sodimm\533mhz\4gb"
"memory\ram\ddr\sodimm\533mhz\8gb"
"memory\ram\ddr\sodimm\533mhz\16gb"
"memory\ram\ddr\sodimm2\633mh\4gb
"memory\ram\ddr\sodimm2\633mh\16gb
"memory\disk"
and so on....
*******************
And I need this Output (pay attention at return correct order output):
var jsondata = [
{
"text": "productone",
"nodes":[ {"text": "level2",
"nodes":[{"text": "level3"}]
}]
},
{
"text": "productwo",
"nodes":[{"text": "level2"},
"nodes":[{"text": "level3",
"nodes":[{text:level4}]
}]
}]
}
}]
Any suggestion?
I threw away my previous answer to replace it with this one.
This should do exactly what you want.
var src = [
"productone",
"productone\\level2\\level3",
"productwo\\level2\\level3\\level4",
"productone\\level2\\dog",
"productone\\level2\\dog\\bark",
"productwo\\level2\\level3a\\level4a",
"productwo\\level2\\level3\\level4\\level5",
"productwo\\food\\desserts\\cookies",
"productwo\\food\\desserts\\cakes",
"productwo\\food\\desserts\\pies",
"productone\\level2\\cat",
"productone\\level2\\cat\\meow"
]
function tempToObj(temp) {
var result = [];
Object.keys(temp).forEach(
function(key) {
var obj = {
text: key
};
var nodes = tempToObj(temp[key]);
if (nodes.length > 0) {
obj.nodes = nodes;
}
result.push(obj);
}
);
return result;
}
function strsToObj(strList) {
var result = [];
var tempResult = {};
function buildNode(parts, idx, obj) {
var key = parts[idx];
obj[key] = obj[key] || {};
idx++;
if (idx < parts.length) {
buildNode(parts, idx, obj[key]);
}
}
strList.forEach(
function(str) {
var parts = str.split('\\');
buildNode(parts, 0, tempResult);
}
);
return tempToObj(tempResult);
}
var obj = strsToObj(src);
console.log(JSON.stringify(obj,0,2));
I found it much easier to just build of an object structure and then convert it into the format you wanted. That simplified the parsing algorithm and yet prevents rebuilding everything each time.
The result of the code above is this:
[
{
"text": "productone",
"nodes": [
{
"text": "level2",
"nodes": [
{
"text": "level3"
},
{
"text": "dog",
"nodes": [
{
"text": "bark"
}
]
},
{
"text": "cat",
"nodes": [
{
"text": "meow"
}
]
}
]
}
]
},
{
"text": "productwo",
"nodes": [
{
"text": "level2",
"nodes": [
{
"text": "level3",
"nodes": [
{
"text": "level4",
"nodes": [
{
"text": "level5"
}
]
}
]
},
{
"text": "level3a",
"nodes": [
{
"text": "level4a"
}
]
}
]
},
{
"text": "food",
"nodes": [
{
"text": "desserts",
"nodes": [
{
"text": "cookies"
},
{
"text": "cakes"
},
{
"text": "pies"
}
]
}
]
}
]
}
]
I have solve my problem and I have transform to Javacript pure code this
Brandon Clapp article
You can string#split each string inside array#map and use array#reduceRight to check for nodes and text value inside your result object. If text key is present at a level, reassign your object to nodes key and populate text key with the current text value.
var strings = ["productone","productone\\level2\\level3","productwo\\level2\\level3\\level4"];
const result = strings.map(string => string.split('\\').reduceRight((r,text, index) => {
if(r['text'])
r['nodes'] = [Object.assign({}, r)];
r['text'] = text;
return r;
},{}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could take a hash table with a nested approach by taking the given part strings as identifiert for nested objects for collecting all data.
Later this proposal deletes unwanted nodes without content.
This approach works for unsorted data.
var array = ["productone", "productone\\level2\\level3", "productwo\\level2\\level3\\level4"],
result = [],
hash = { _: result };
array.forEach(function (a) {
a.split('\\').reduce(function (r, k) {
if (!r[k]) {
r[k] = { _: [] };
r._.push({ text: k, nodes: r[k]._ });
}
return r[k];
}, hash);
});
result.forEach(function clean(o) {
if (o.nodes.length) {
o.nodes.forEach(clean);
} else {
delete o.nodes;
}
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to get an JSON Object based in key using jquery

I'm using jsTree and have tree an structured JSON object.
[{
"id": 1,
"text": "TEXT_ONE",
"children": [
{
"id": 2,
"text": "TEXT_TWO",
"children": [
{
"id": 3,
"text": "TEXT_THREE",
"children": [
]
},
{
"id": 4,
"text": "TEXT_FOUR",
"children": [
]
}
]
},
{
"id": 5,
"text": "TEXT_FIVE",
"children": [
]
}
]
},
{
"id": 6,
"text": "TEXT_SIX",
"children": [ ]
}]
I want to get the the object based on the "id" of the object.
For example if i have a function getIdFromTree(3) it will return me the JSON object as following:
{
"id": 3,
"text": "TEXT_THREE",
"children": []
},
How I do that in Javascript/JQuery?
Try this
function getObjById (tree, id) {
if(tree.id === id) {
return tree;
}
if(tree.children) {
for(var i = 0, l = tree.children.length; i < l; i++) {
var returned = getObjById(tree.children[i], id);
if(returned) {
// so that the loop doesn't keep running even after you find the obj
return returned;
}
}
}
}
Call this as follows
getObjById({children: tree}, 3); // tree is the array object above.
function findById (tree, id) {
var result, i;
if (tree.id && tree.id === id) {
result = tree;
// Revalidate array list
} else if (tree.length) {
for (i = 0; i < tree.length; i++) {
result = findById(tree[i], id);
if (result) {
break;
}
}
// Check childrens
} else if (tree.children) {
result = findById(tree.children, id);
}
return result;
}
Use filter Methode off Array
data.filter(function (obj){ obj.id== 3});
try this.... Es6
function *getObjectById(data, id) {
if (!data) return;
for (let i = 0; i< data.length; i++){
let val = data[i];
if (val.id === id) yield val;
if (val.children) yield *getObjectById(val.children , id);
}
}
now
getObjectById(arrayOfObjects, id).next().value;
try this with most effective and efficient way..
function getObjById (tree, id) {
for(var i= 0;i<tree.length;i++)
{
if(tree[i].id===id)
{
return tree[i];
}
if(tree[i].children)
{
var returned = getObjById(tree[i].children,id);
if(returned!= undefined)
return returned;
}
}
};
link:
https://jsfiddle.net/aa7zyyof/14/

js loop after a certain json node

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

Change key name in nested JSON structure

I have a JSON data structure as shown below:
{
"name": "World",
"children": [
{ "name": "US",
"children": [
{ "name": "CA" },
{ "name": "NJ" }
]
},
{ "name": "INDIA",
"children": [
{ "name": "OR" },
{ "name": "TN" },
{ "name": "AP" }
]
}
]
};
I need to change the key names from "name" & "children" to say "key" & "value". Any suggestion on how to do that for each key name in this nested structure?
I don't know why you have a semicolon at the end of your JSON markup (assuming that's what you've represented in the question), but if that's removed, then you can use a reviver function to make modifications while parsing the data.
var parsed = JSON.parse(myJSONData, function(k, v) {
if (k === "name")
this.key = v;
else if (k === "children")
this.value = v;
else
return v;
});
DEMO: http://jsfiddle.net/BeSad/
Try this:
function convert(data){
return {
key: data.name,
value: data.children.map(convert);
};
}
Or if you need to support older browsers without map:
function convert(data){
var children = [];
for (var i = 0, len = data.children.length; i < len; i++){
children.push(convert(data.children[i]));
}
return {
key: data.name,
value: children
};
}
You could use a function like this :
function clonerename(source) {
if (Object.prototype.toString.call(source) === '[object Array]') {
var clone = [];
for (var i=0; i<source.length; i++) {
clone[i] = goclone(source[i]);
}
return clone;
} else if (typeof(source)=="object") {
var clone = {};
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
var newPropName = prop;
if (prop=='name') newPropName='key';
else if (prop=='children') newPropName='value';
clone[newPropName] = clonerename(source[prop]);
}
}
return clone;
} else {
return source;
}
}
var B = clonerename(A);
Note that what you have isn't a JSON data structure (this doesn't exist as JSON is a data-exchange format) but probably an object you got from a JSON string.

Categories