Javascript or jQuery way to display random-level JSON as HTML - javascript

I would like to parse and display arbitrary-level JSON snippets as HTML. By arbitrary-level I mean there is no pre-definied structure. For example:
"CustomFields": [
{
"Main": [
{
"None": [
{
"SDOM Date": "2014-12-24"
},
{
"User Defined 31": "2009-03-02"
}
]
},
{
"Contract Data": [
{
"Status2": "Active"
},
{
"User Defined 112": "N"
}
]
}
]
}
Besides the CustomFields root element, everything under it is unpreditable. But basically there are layers of objects which are each an array of other objects, until you finally arrive at an object value. In the example above there are 4 levels. But there can be any number of them.
What I'd like is to display something like:
Main
None
SDOM Date: 2014-12-24
User Defined 31: 2009-03-02
Contract Data
Status2: Active
User Defined 112: N

Try this..
var json = {"CustomFields": [
{
"Main": [
{
"None": [
{
"SDOM Date": "2014-12-24"
},
{
"User Defined 31": "2009-03-02"
}
]
},
{
"Contract Data": [
{
"Status2": "Active"
},
{
"User Defined 112": "N"
}
]
}
]
}]};
function jsonToHtml(array){
var html = '<ul>';
for (var i=0; i<array.length; i++){
if (typeof array[i] == 'object'){
for (var j in array[i]){
var innerHTML = (typeof array[i][j]=='object')?jsonToHtml(array[i][j]):' : '+array[i][j];
html += '<li>'+j+innerHTML+'</li>';
}
}
}
html += '</ul>';
return html;
}
aaa.innerHTML = jsonToHtml(json.CustomFields);
<div id="aaa"></div>

Related

Return object with specific key:value pair in an array nested in another array - Javascript

I'm trying return an object from the code below that has the key value pair of name:sparky and return the entire metadata and stats array for that object.
I don't want to use Object.values(objectArray)[0] because this data is coming from an API and I expect the objects position in the array to change in the future.
I've tried objectArray.find but I don't know how to use that to find a value of an array which is inside another array. The value for name will always be unique and the actual objectArray has many more objects inside of it.
Help would be greatly appreciated!
Code
objectArray = [
{
"metadata": [
{
"key": '1',
"name": "sparky"
}
],
"stats": [
{
"statsFieldOne": "wins"
},
{
"statsFieldTwo": "kills"
}
]
},
{
"metadata": [
{
"key": '1',
"name": "abby"
}
],
"stats": [
{
"statsFieldOne": "wins"
},
{
"statsFieldTwo": "kills"
}
]
}
]
Desired result
{
"metadata": [
{
"key": '1',
"name": "sparky"
}
],
"stats": [
{
"statsFieldOne": "wins"
},
{
"statsFieldTwo": "kills"
}
]
}
I guess you can do following:
function getObjectForName(key, name) {
var filteredMetadata = [];
for(var i=0; i< objectArray.length; i++) {
filteredMetadata = objectArray[i].metadata.filter((val) => val[key] === name)
if(filteredMetadata.length) {
return objectArray[i];
}
}
}
getObjectForName('name', 'sparky')
What this code basically does is, iterates through all objects and check if name is sparky, if yes just break it. If you want to return all occurrences matching name, you need to add all of them to another array and return it.
You can simply use Reduce
let objectArray = [{"metadata":[{"key":'1',"name":"sparky"}],"stats":[{"statsFieldOne":"wins"},{"statsFieldTwo":"kills"}]},{"metadata":[{"key":'1',"name":"abby"}],"stats":[{"statsFieldOne":"wins"},{"statsFieldTwo":"kills"}]}]
let op = objectArray.reduce(( op,{metadata,stats} ) =>{
let found = metadata.find(({name})=>name==='sparky')
if(found){
op.push({metadata:found,stats})
}
return op
},[])
console.log(op)

Looping through a JavaScript object

I'm trying to loop through this JavaScript object but it's only returning the last key.
Here's my code
var array = [
{
"outfit": {
"url": "http://www.nintendo.co.uk",
"title":"T-shirt",
"price":"£20"
}
},
{
"outfit": {
"url": "http://www.nintendo.co.uk",
"title":"T-shirt",
"price":"£720"
}
},
{
"outfit": {
"url": "http://www.nintendo.co.uk",
"title":"T-shirt",
"price":"£9920"
}
}
];
for(var i=0; i<array.length; i++){
console.log(array[i]);
$('.slide .content').each(function(index){
if(i == index) {
console.log(i + "==" + index);
var contentDiv = $('.slide .content')[index];
contentDiv.innerHTML = "";
contentDiv.innerHTML = ''+ array[i].title + '<span>'+ array[i].price +'</span>'
}
});
}
I'm basically trying to loop through the data, extracting it for a look-book carousel. Then append each piece of data in $('.slide .content') for each slide of the carousel.
Any help would greatly be appreciated. Many thanks
Edited
var array = [
{
"outfit": [
{
"link": {
"url": "http://www.nintendo.co.uk",
"title":"T-shirt",
"price":"£20"
},
},
{
"link": {
"url": "http://www.bbc.co.uk",
"title":"Trousers",
"price":"£60"
}
}
]
},
{
"outfit": [
{
"link": {
"url": "http://www.nintendo.co.uk",
"title":"Dress",
"price":"£920"
}
}
]
}
];
array.forEach(function(value, index ){
value.outfit.forEach(function( outfitValue, outfitIndex){
console.log(outfitValue.link.title);
});
});
Result
T-shirt
Trousers
Dress
https://jsfiddle.net/jzpL8dnm/13/
I changed the structure of your code. It may help you to solve your problem.
var array = [
{
"outfit": {
"link": {
"url": "http://www.nintendo.co.uk",
"title":"T-shirt",
"price":"£20"
},
"link": {
"url": "http://www.bbc.co.uk",
"title":"Trousers",
"price":"£60"
}
}
},
{
"outfit": {
"link": {
"url": "http://www.nintendo.co.uk",
"title":"Dress",
"price":"£920"
}
}
}
];
for(var key in array){
console.log(array[key]);
}
I found that if we are having same keys in a JavaScript object then on traversing JavaScript object by transpiler/compiler it will get the updated info of keys. So keys should be unique if you really want to achieve it Associative array are the most convenient way because indexing will help you to retrieve data either the data is duplicate or not.
second way: if you want to use only js object then create array in js object where you have same key.
You have the same keys.
Keys in JS objects must be unique.

Update Objects of Objects after Deleting Data

I am stuck in a situation where I need to update my object of objects to update , the real problem is i want to update its index with the deleted item for example:
{
"selected": null,
"lists": {
"0": [
{
"key": "Survey Meta Data"
}
],
"1": [
{
"key": "Assessment"
}
],
"2": [
{
"key": "Income Survey Process"
}
],
"3": [
{
"key": "Appeal Process"
}
]
}
}
suppose i deleted the lists[0]:
now the current items will be like:
{
"selected": null,
"lists": {
//"0": [ as deleted so no need just update the others without losing data
// {
// "key": "Survey Meta Data"
// }
//],
"0": [ //now it gets 0
{
"key": "Assessment"
}
],
"1": [//now it gets 1
{
"key": "Income Survey Process"
}
],
"2": [//now it gets 2
{
"key": "Appeal Process"
}
]
}
}
app.js
function add(data)
{
for (var i=0;i<4;i++)
{
$scope.models.lists[i]=[{"key":data[i].id}]
}
}
function remove(key)
{
for (var i=0;i<$scope.len;i++)
{
for (var s=0;s<$scope.models.lists[i].length;s++)
{
if(key==$scope.models.lists[i][s].key) {
delete $scope.models.lists[i]// deleted now want to update
break;
}
}
}
}
Quite simple. Dont delete the wanted but the last, and copy one position backward after the element you want to delete:
function remove(key){
var found=false;
var list=$scope.models.lists;
//get the length to properly iterate, requires proper keys e.g. 0,1,2,3
var length=+Object.keys(list).sort().reverse()[0]+1;
//iterate over
for (var i=0;i<length-1;i++){
if(key===list[i][0].key || found) {
//if found override current with next
found=true;
list[i]=list[i+1];
}
}
//delete last one if weve found sth before, or if the last is the one to be deleted
if(list[i][0].key===key || found){
delete list[i];
}
}
http://jsbin.com/casikuxoha/edit?console
or with multiple:
http://jsbin.com/tewaveyiwa/1/edit?console
In my previous answer I was completely oblivious of your needs.
Here is the code that allows you to delete any item of the list (copy/paste this in a pristine component and look at the console log) :
list = {
'selected': null,
lists: {
'0': [{ 'key': 'Survey Meta Data' }],
'1': [{ 'key': 'Assessment' }],
'2': [{ 'key': 'Income Survey Process' }],
'3': [{ 'key': 'Appeal Process' }]
}
};
constructor() { }
ngOnInit() {
this.removeItem('1');
}
removeItem(index: string) {
let keys = Object.keys(this.list.lists);
keys = keys.filter(k => k !== index);
let myNewVar = { selected: null, lists: {} };
for (let key of keys) { myNewVar.lists[key] = this.list.lists[key]; }
console.log(myNewVar);
}

javascript multi dimensional array

I am trying to create a multidimentional arrya in javascript where I can add items in the following fashion:
var foo = {
"Internal": {
"0":
{
"pic_id":"15011",
"description":"Picture of a cpu",
"localion":"img.cloudimages.us/2012/06/02/mycpu.png",
"type":"png"
},
"1":{
"pic_id":"15011",
"description":"Picture of a cpu",
"localion":"img.cloudimages.us/2012/06/02/mycpu.png",
"type":"png"
}
},
"External":
{
"0":
{
"pic_id":"15014",
"description":"Picture of a cpu",
"localion":"img.cloudimages.us/2012/06/02/mycpu.png",
"type":"png"
}
}
};
but I don't know how to get my value into the main category. I got the following code
vm.classificationNames = [,];
for (var i = 0; i < vm.classificationNames.length; i++) {
vm.allGroupsInClassifications.push(vm.classificationNames[i]);
}
for (var i = 0; i < data.length; i++) {
var item = data[i];
if (item.classification != null) {
} else if (item.classification == null) {
vm.classificationNames['Internal'][item];
}
}
console.log(vm.classificationNames);
I also tried to use the following without any luck:
vm.classificationNames['Internal'].push(item);
Does anyone know what I'd be doing wrong? thanks for the help in advance.
Thats because its an object, not an array.
Change your inner object to an array and push will work
var foo = {
"Internal": [ // <--- Note the square braces
{
"pic_id": "15011",
"description": "Picture of a cpu",
"localion": "img.cloudimages.us/2012/06/02/mycpu.png",
"type": "png"
},
{
"pic_id": "15011",
"description": "Picture of a cpu",
"localion": "img.cloudimages.us/2012/06/02/mycpu.png",
"type": "png"
}
], // <--- Note the square braces
"External": [ // <--- Note the square braces
{
"pic_id": "15014",
"description": "Picture of a cpu",
"localion": "img.cloudimages.us/2012/06/02/mycpu.png",
"type": "png"
}
] // <--- Note the square braces
};
foo['Internal'].push(item);
Try iterating over the dictionary with
for(var key in vm.classificationNames) {
var entry = vm.classificationNames[entry];
/*....*/

JSON Data Fuzzy merge

I have a JSON data like this
{
"array": {
"InvestmentsDeposits": {
"NAME": "Investments & Deposits",
"PARENT": [
{
"CONTENT_ID": "Promotions",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
}
]
},
"InvestmentsDeposits$$$d": {
"NAME": "Deposits",
"PARENT": [
{
"CONTENT_ID": "NewPromotion",
"text" : "newtext"
}
]
}
}
}
I need to search for fuzzy data and merge. For example InvestmentsDeposits and InvestmentsDeposits$$$d need to be merged because it matches closely in name
Need to use javascript for this
For now I can make sure source data will always have $$$d at the end to merge with the target data without $$$d i.e., InvestmentDeposits.
My final merged content should be like this
{
"array": {
"InvestmentsDeposits": {
"NAME": "Deposits",
"PARENT": [
{
"CONTENT_ID": "NewPromotion",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
"text": "newtext"
}
]
}
}
}
any help on this one?
What I have tried so far
var json0 = {
"InvestmentsDeposits": {
"NAME": "Investments & Deposits",
"PARENT": [
{
"CONTENT_ID": "Promotions",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
}
]
}
};
var json1 =
{
"InvestmentsDeposits$$$d": {
"NAME": "Deposits",
"PARENT": [
{
"CONTENT_ID": "NewPromotion",
"text" : "newtext"
}
]
}
};
// Merge object2 into object1, recursively
$.extend( true, json0, json1 );
I am able to merge the data if i am able to split the InvestmentDeposits and InvestmentDeposits$$$d in to two distinct JSON objects but how to split and move the $$$d data in to another object? to make the jquery extend work
Use Object.keys() to find an object's keys and figure out what data to move over. You can compare the first key with the others to find matches, then remove the keys you just looked at until all of them are gone. Here's an example with a similar object.
var dat = {
"InvestmentsDeposits": {
"NAME": "Investments & Deposits",
"CONTENT_ID": "Promotions",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
}, "InvestmentsDeposits$$$d": {
"NAME": "Deposits",
"CONTENT_ID": "NewPromotion",
"text" : "newtext"
},
"NotLikeTheOthers": {
"Um": "Yeah."
}
};
var result = {}; // This will be the merged object
var keys = Object.keys(dat); // Contains keys
while(keys.length) {
var i=1;
for(; i<keys.length; i++) { // Find matches
if(keys[0] == keys[i] + '$$$d') { // Match type 1
result[keys[i]] = dat[keys[i]]; // Copy orig
for(var j in dat[keys[0]]) { // Replace values
result[keys[i]][j] = dat[keys[0]][j];
}
keys.splice(i,1);
keys.shift();
i = 0;
break;
} else if(keys[i] == keys[0] + '$$$d') { // Reverse matched
result[keys[0]] = dat[keys[0]];
for(var j in dat[keys[i]]) {
result[keys[0]][j] = dat[keys[i]][j];
}
keys.splice(i,1);
keys.shift();
i = 0;
break;
}
}
if(i > 0) { // Didn't find a match
result[keys[0]] = dat[keys[0]];
keys.shift();
}
}
alert(JSON.stringify(result));
Note that Object.keys() requires IE9+.

Categories

Resources