json recursive function does not send back complete Json Object - javascript

I have the following JsonObject
let jsonObject = {
"augmentedReality": {
"enabled": false,
"augmentedRealitySettings" : [
{
"assetId": 7
}
]
}
}
I am have written a recursive function that looks the following
isAssetId(jsonObject: any) {
for (let key in jsonObject) {
if (typeof jsonObject[key] === "object") {
jsonObject[key] = this.isAssetId(jsonObject[key]);
} else {
if(key=='assetId'){
jsonObject[key]=3;
}} }
return jsonObject;
}
My goal is to change the assetId wherever it exists in the jsonObject. This JSON is just an example, while assetId could be far in the deeper.
The problem with the code is that when it's successfully executed it returns the following JSON object
I call the function with the following:
jsonObject= isAssetId(jsonObject);
console.log(jsonObject);
and I get the following results.
{
augmentedReality: { enabled: false, augmentedRealitySettings: [
[Object] ] }
}
The Object should show the data it has not the object.
I cannot figure out what seems to be the problem. Any help would be appreciated?
UPDATE:
I wrote the code into the following site
here
Weirdly it's working fine here, but it does not work on my typescript on NestJs? Now what is the reason?

There is something wrong with the logic of your code. At one point you are looping through an array like an object. You could do something like:
var json = isAssetId(jsonObject);
console.log(JSON.stringify(json));
function isAssetId(jsonObject) {
for (let key in jsonObject) {
if(Array.isArray(jsonObject[key])){
for (const [i ,element] of jsonObject[key].entries()) {
jsonObject[key][i] = isAssetId(element);
}
}
else if (typeof jsonObject[key] === "object") {
jsonObject[key] = isAssetId(jsonObject[key]);
} else {
if(key=='assetId'){
jsonObject[key]=3;
}} }
return jsonObject;
}

The problem is "this" keyword in the function. For more information please check post.
let jsonObject = {
"augmentedReality": {
"enabled": false,
"augmentedRealitySettings" : [
{
"assetId": 7
}
]
}
}
var json = isAssetId(jsonObject);
console.log(JSON.stringify(json));
isAssetId(jsonObject) {
for (let key in jsonObject) {
if (typeof jsonObject[key] === "object") {
jsonObject[key] = isAssetId(jsonObject[key]);
} else {
if(key=='assetId'){
jsonObject[key]=3;
}} }
return jsonObject;
}

Related

Nested Array Of JSON Looping in Typescript

I'm trying to get the value of "id" of the below mentioned array of json but i'm not able to get the result because it is surrounded by two "[[" array braces, can anybody please help me out, Also im getting these array of JSON from another loop if the loop runs single time i'm getting single array brace "[" , if the loop runs multiple times i'm gettin "[[" braces...
[
[
{
"attributes":{
"id":"Task_1yett21"
},
"incoming":"SequenceFlow_112bxv0",
"outgoing":"SequenceFlow_1gkdhq3"
},
{
"attributes":{
"id":"Task_0i5lteb"
},
"incoming":"SequenceFlow_1gkdhq3",
"outgoing":"SequenceFlow_1gjii2n"
},
{
"attributes":{
"id":"Task_1v37yfe"
},
"incoming":"SequenceFlow_1gjii2n",
"outgoing":"SequenceFlow_0bygyft"
}
]
]
I'm calling this function to get the JSON objects in the above array...
var getAllValuesOfKey = function (dataObj, queryKey) {
var resultArr = [];
if (!queryKey) {
return resultArr;
}
function execute(dataObj, queryKey) {
Object.keys(dataObj).forEach(function (key, index) {
if (typeof dataObj[key] == 'object' && !(dataObj[key] instanceof Array)) {
if (key == queryKey) {
resultArr.push(dataObj[key]);
}
execute(dataObj[key], queryKey);
} else if (key == queryKey) {
resultArr.push(dataObj[key]);
}
});
}
execute(dataObj, queryKey);
return resultArr;
}
var searchKey = 'task';
var result=getAllValuesOfKey(obj1, searchKey);
You can select the inner array in your loop with index 0 on the outer array, like this:
var myDoubleArray: any = [[{...}, {...}, {...}]];
for (let i = 0; i < myDoubleArray[0].length; i++) {
console.log(myDoubleArray[0][i].attributes.id);
}
If the arrays are still in JSON format, you need to first parse them to JavaScript before you can loop through the data. This can be done with JSON.parse().
var arr = [
[
{
"attributes":{
"id":"Task_1yett21"
},
"incoming":"SequenceFlow_112bxv0",
"outgoing":"SequenceFlow_1gkdhq3"
},
{
"attributes":{
"id":"Task_0i5lteb"
},
"incoming":"SequenceFlow_1gkdhq3",
"outgoing":"SequenceFlow_1gjii2n"
},
{
"attributes":{
"id":"Task_1v37yfe"
},
"incoming":"SequenceFlow_1gjii2n",
"outgoing":"SequenceFlow_0bygyft"
}
]
]
for (var i in arr[0]) {
//arr[0][i].attributes.id will give you the id
console.log(arr[0][i].attributes.id);
}

How the java script complex object and complex array iterate?

Below is running code snippet for the javascript object and array.
I have one jsonObj and here the ResultElementLevel could be the array or
object.
According to I just put if else condition and compare if Array and 'object'.
My question is,How would it be possible without if else condition?
can we write one function which compare object and Array inside single if.
The jsonObj is populating dynamically.
Here it would be possible CHECK object is also come into the Array or Object.
var jsonObj = {
"Response": {
"Errors": {
"Check": {
"_attributes": {
"id": "51416",
"name": "lucyocftest090601"
},
"CheckLevel": {
},
"ResultElementLevel": {
"_text": "Line No (2) [Missing Reporting Category] "
}
}
},
"Success": {
}
}
}
iterateObjorArr(jsonObj);
function iterateObjorArr(jsonObj){
let checkArr = jsonObj.Response.Errors.Check;
let checkID = checkArr._attributes.id;
let checkName = checkArr._attributes.name;
let status = 'failed';
let resultElementLevel = checkArr.ResultElementLevel;
let errorUploadArr = [];
let errorUploadObj;
if (Array.isArray(resultElementLevel)) {
resultElementLevel.map(function (data, index) {
errorUploadObj = {
'id': checkID,
'checkName': checkName,
'status': status,
'errors/warnings': data._text
};
errorUploadArr.push(errorUploadObj);
});
} else {
if (typeof (resultElementLevel) === 'object') {
errorUploadObj = {
'id': checkID,
'checkName': checkName,
'status': status,
'errors/warnings': resultElementLevel._text
};
errorUploadArr.push(errorUploadObj);
}
}
console.log("errorUploadArr", errorUploadArr);
}
You can test to see if resultElementLevel has the length property or not using hasOwnProperty(). Arrays have a length while objects do not (generally):
if (resultElementLevel.hasOwnProperty('length')) {
// Handle it as an array
} else {
// Handle as an object
}
This will, however, only work if the object assigned to resultElementLevel is guaranteed to not have a length property.
My question is,How would it be possible without if else condition? can we write one function which compare object and Array inside single if.
I don't think you'd want to get rid of the condition, but being able to deal with the passed data the same way, wether it's an array, a single item, or null/undefined
You could normalize the data first
function toArray(value){
return value == null? []:
Array.isArray(value)? value:
//isArrayLike(value)? Array.from(value):
[value];
}
//Objects that look like Arrays
function isArrayLike(value){
return value !== null && typeof value === "object" && value.length === (value.length >>> 0);
}
so that from here on, you always deal with an Array:
let errorUploadArr = toArray(checkArr.ResultElementLevel)
.map(function(item){
return {
id: checkID,
checkName: checkName,
status: status,
"errors/warnings": item._text
};
});
var jsonObj = {
Response: {
Errors: {
Check: {
_attributes: {
id: "51416",
name: "lucyocftest090601"
},
CheckLevel: {},
ResultElementLevel: {
_text: "Line No (2) [Missing Reporting Category] "
}
}
},
Success: {}
}
};
iterateObjorArr(jsonObj);
function toArray(value) {
return value == null ? [] :
Array.isArray(value) ? value :
//isArrayLike(value)? Array.from(value):
[value];
}
//Objects that look like Arrays
function isArrayLike(value) {
return value !== null && typeof value === "object" && value.length === (value.length >>> 0);
}
function iterateObjorArr(jsonObj) {
let checkArr = jsonObj.Response.Errors.Check;
let checkID = checkArr._attributes.id;
let checkName = checkArr._attributes.name;
let status = "failed";
let errorUploadArr = toArray(checkArr.ResultElementLevel)
.map(function(data) {
return {
id: checkID,
checkName: checkName,
status: status,
"errors/warnings": data._text
}
});
console.log("errorUploadArr", errorUploadArr);
}
.as-console-wrapper{top:0;max-height:100%!important}

extract fields in javascript

I have a dictionary where i want to extract some fields with their keys. So what i want is call a function where i pass this dictionary and the keys.
var posts = {
"code":"ok",
"data":[
{
"id":1,
"username":"example1",
"data":
{
"id":4,
"name":"fran"
},
},
{
"id":2,
"username":"example2",
"data":
{
"id":5,
"name":"manuel"
}
}
]
};
So I would like to have a new dictionary where i have the nested value as a simple dictionary value.
[{
"id":1,
"username":"example1",
"name":"fran"
},
"id":2,
"username":"example2",
"name":"manuel"
}}
function dict(obj)
{
var list = Object.assign({},obj).data;
list.forEach((e,i,a) => {
e.name = e.data.name;
delete e.data;
});
return list;
}
that's how you dictionary function should look
I have tried this one. I think i have problem because i am creating a dictionary when node is "name" in the iteration. So i want to confirm if it's OK or there is any another way to do this.
var list = [];
var dict = {};
function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
console.log(property + " " + obj[property]);
dict[property] = obj[property];
if(property=="name"){
list.push(dict);
dict ={};
}
}
}
}
return list;
}
var simplified = iterate(posts.data, '');
console.log(simplified);

Access multilevel key from a JSON object in javascript

I have a javascript function which returns the response like this( I am using nodejs and ejs):
"index_1": {
"mappings": {
"type_1": {
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": "string"
}
}
},
"type_2": {
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": "string"
},
"field_3": {
"type": "string"
}
}
}
}
}
Now, I need to access 2nd or third level key from the response. Suppose if I want a list like this:
type_1
type_2
or
field_1
field_2
field_3
How can I do that? If I use callback(Object.keys(response)) then it returns index_1. Can anyone point me to right direction?
To get the keys of a sub-object, you need to pass this particular sub-object to Object.keys():
var data = {"index_1":{"mappings":{"type_1":{"properties":{"field_1":{"type":"string"},"field_2":{"type":"string"}}},"type_2":{"properties":{"field_1":{"type":"string"},"field_2":{"type":"string"},"field_3":{"type":"string"}}}}}};
console.log(Object.keys(data.index_1.mappings));
// ["type_1", "type_2"]
console.log(Object.keys(data.index_1.mappings.type_2.properties));
// ["field_1", "field_2", "field_3"]
There is no simple one-liner, I suppose.
Object.keys( object );
returns only first level keys (that's the reason you get index_1).
Solution 1
If you know, that response, has alway a structure of:
var jsonObject = {
"index_1" : {
"mappings": {
"type1" : ... ,
"type2" : ...
}
};
Then you only need to pass:
callback(Object.keys(jsonObject.index1.mappings));
That way you'll get third level keys.
But if you don't know the structure, or want to access keys of any level, then recursion might be helpful.
var jsonObject = {
"index_1" : {
"mappings": {
"type1" : { field1 : {}, field2 : 2} ,
"type2" : {}
}
}
};
// 1..N, and 1 means you want to get **index_1**
function getNthLevelKeys( json, level ) {
var keys = [];
var currLvlKeys = Object.keys(json);
level = level - 1;
if ( typeof json !== 'object' || json === null) {
return [];
}
if ( level > 0 ) {
for (var i = 0; i < currLvlKeys.length; i++) {
keys = keys.concat(getNthLevelKeys( json[ currLvlKeys[i] ] , level ));
}
}
if (level === 0) {
return currLvlKeys;
}
if (level < 0) {
throw new Error("Cannot access level "+level+" of this object");
}
return keys;
}
console.log(getNthLevelKeys( jsonObject , 1));
console.log(getNthLevelKeys( jsonObject , 2));
console.log(getNthLevelKeys( jsonObject , 3));
console.log(getNthLevelKeys( jsonObject , 4));

Creating json in specific format using javascript

I have a complex javascript code which when simplified is as below..
function getjson1() {
return {
'json1': {
id: 'jsonid1'
}
};
}
function getjson2() {
return {
'json2': {
id: 'jsonid2'
}
};
}
myjson = [];
myjson.push(getjson1());
myjson.push(getjson2());
function finaljson() {
return {
'json': myjson
};
}
console.log(JSON.stringify(finaljson()));
Now the result of this code is
{"json":[{"json1":{"id":"jsonid1"}},{"json2":{"id":"jsonid2"}}]}
Now this code I need to change such that I can get rid of the array and can traverse the json object like.. json.json1.id, etc..
One example could be as below..
{"json":{"json1":{"id":"jsonid1"},"json2":{"id":"jsonid2"}}}
Any help is sincerely appreciated.
Thanks
Well if you don't want an array, don't use one. First, a jQuery-based solution:
myjson = {};
myjson = $.extend(myjson, getjson1());
myjson = $.extend(myjson, getjson2());
In native JavaScript, you can use the following function:
function extend (target, source) {
Object.keys(source).map(function (prop) {
target[prop] = source[prop];
});
return target;
};
This way, the first code becomes this:
myjson = {};
myjson = extend(myjson, getjson1());
myjson = extend(myjson, getjson2());
You are pushing it to an array so you are getting an array.
use this simple add function to push it in an object in the format you want.
First key in the function returns will be the key in the end object.
function getjson1() {
return {
'json1': {
id: 'jsonid1'
}
};
}
function getjson2() {
return {
'json2': {
id: 'jsonid2'
}
};
}
function add(obj, toadd) {
for(var key in toadd) {
if(toadd.hasOwnProperty(key)) {
obj[key] = toadd[key];
break;
}
}
return obj;
}
myjson = {};
add(myjson,getjson1());
add(myjson,getjson2());
function finaljson() {
return {
'json': myjson
};
}
console.log(JSON.stringify(finaljson()));

Categories

Resources