Update Objects of Objects after Deleting Data - javascript

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

Related

how to loop inside object array Angular

I want to display values from my json but I don't know how to do it. Is it possible to loop inside an object array ? i don't know if the keyvalue pipe can help me but I want to do without.
how to get the student2 and also the name to display it ?
thanks everyone.
json
{
"student": {
"student1": [],
"student2": [
{
"id": "123",
"name": "boot"
},
"student3": [],
]
},
"teacher": {
"teacher1": [],
"teacher2": [
{
"id": "123456",
"name": "toto"
},
]
}
}
ts.file
get(){
this.service.getAll().subscribe((data:any) => {
object.keys(data).length > 0;
})
}
Assuming your JSON object from your GET request looks like the one you posted above simply do:
get(){
this.service.getAll().subscribe((data:any) => {
data.student.forEach(element => {
for (let key in element) {
console.log(" key:", key, "value:", element[key]);
for (let val in element[key]) {
console.log(" value:", val);
}
}
});
})
}

How to create a JS object and append it to an array

I have the following data :
const data=
{
"1": [
{
"sales_project_id": 5,
"sales_project_name": "name",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
},
{
"sales_project_id": 6,
"sales_project_name": "name2",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
}
],
"2": [],
"4": []
}
These data are grouped in my backend based on their Status , in this case im only showing 2 status , but they are dynamic and can be anything the user defines.
What i wish to do is to transform the above data into the format below :
const data =
{
columns: [
{
id: // id of status here,
title: //label of status here,
cards: [
{
id : //sales_project_id here,
title: //sales_project_name here,
},
]
},
{
id: // id of status here,
title: //label of status here,
cards: [
{
id : //sales_project_id here,
title: //sales_project_name here,
},
]
}
]}
My guess would be to iterate over the data , however i am pretty unfamiliar with doing so , would appreciate someone's help!
Here is what i could come up with so far:
const array = []
Object.keys(a).map(function(keyName, keyIndex) {
a[keyName].forEach(element => {
#creating an object of the columns array here
});
})
after some trial and error , manage to accomplish this , however , im not sure if this is a good method to do so.
Object.keys(projects).map(function(keyName, keyIndex) {
// use keyName to get current key's name
// and a[keyName] to get its value
var project_object = {}
project_object['id'] = projects[keyName][0].id
project_object['title'] = projects[keyName][0].label
project_object['description'] = projects[keyName][0].description
console.log( projects[keyName][1])
var card_array = []
projects[keyName][1].forEach(element => {
var card = {}
card["id"] = element.sales_project_id
card["title"] = element.sales_project_name
card["description"] = element.sales_project_est_rev
card_array.push(card)
});
project_object["cards"] = card_array
array.push(project_object)
})
Im basically manipulating some the scope of the variables inorder to achieve this
See my solution, I use Object.keys like you, then I use reduce:
const newData = { columns: Object.keys(data).map((item) => {
return data[item].reduce((acc,rec) => {
if (typeof acc.id === 'undefined'){
acc = { id: rec.project_status.id, title: rec.project_status.label, ...acc }
}
return {...acc, cards: [...acc.cards, { id:rec.sales_project_id, title:rec.sales_project_name}]}
}, {cards:[]})
})}
See full example in playground: https://jscomplete.com/playground/s510194
I'd just do this. Get the values of data using Object.values(data) and then use reduce to accumulate the desired result
const data=
{
"1": [
{
"sales_project_id": 5,
"sales_project_name": "name",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
},
{
"sales_project_id": 6,
"sales_project_name": "name2",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
}
],
"2": [],
"4": []
};
const a = Object.values(data)
let res =a.reduce((acc, elem)=>{
elem.forEach((x)=>{
var obj = {
id : x.project_status.id,
title : x.project_status.label,
cards : [{
id: x.sales_project_id,
title: x.sales_project_name
}]
}
acc.columns.push(obj);
})
return acc
},{columns: []});
console.log(res)

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

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>

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+.

Remove JSON object with same id recursively

I have a JSON list with duplicates I need to remove, but I can't find a way to do it.
This is the solution that I have.
I want to keep the first item found with a given ID, and remove the next ones with the same ID.
The problem is, it tries to remove even the first item.
var gindex = [];
function removeDuplicate(list) {
$.each(list, function(i, val){
console.log(val.id);
console.log(gindex);
if($.inArray(val.id, gindex) == -1) { //in array, so leave this item
gindex.push(val.id);
}
else // found already one with the id, delete it
{
list.splice(i, 1);
}
if(val.children) {
val.children = removeDuplicate(val.children);
}
});
return list;
}
gindex = [];
list = removeDuplicate(parsed_list);
console.log(window.JSON.stringify(list));
finally, this is the original list :
[
{
"id": 0,
"children": [
{
"id": 1,
"children": [
{
"id": 2, // with my algorithm, this one get also flagged for deletion
}
]
},
{
"id": 2, // remove this one
},
{
"id": 3,
},
{
"id": 4, // with my algorithm, this one get also flagged for deletion
"children": [
{
"id": 5, // with my algorithm, this one get also flagged for deletion
"children": [
{
"id": 6, // with my algorithm, this one get also flagged for deletion
}
]
}
]
},
{
"id": 5, // remove this one
"children": [
{
"id": 6, // remove this one
}
]
},
{
"id": 6, // remove this one
},
{
"id": 7,
}
]
}
]
and this is the result I would like to obtain
[
{
"id": 0,
"children": [
{
"id": 1,
"children": [
{
"id": 2,
}
]
},
{
"id": 3,
},
{
"id": 4,
"children": [
{
"id": 5,
"children": [
{
"id": 6,
}
]
}
]
},
{
"id": 7,
}
]
}
]
thank you for your reply.
I tried creating my own logic for this (probably more general than what you want), but it may help you debug your code. See the jsFiddle.
The core of the logic is
/**
* Walk through an object or array and remove duplicate elements where the 'id' key is duplicated
* Depends on a seenIds object (using it as a set)
*/
function processData(el) {
// If the element is an array...
if ($.isArray(el)) {
for (var i = 0; i < el.length; i++) {
var value = el[i];
processData(value);
// If the child is now empty, remove it from the array
if (checkForEmpty(value)) {
el.splice(i, 1);
i--; // Fix index after splicing (http://stackoverflow.com/a/9882349/1370556)
}
}
}
// If the element is an object...
else if ($.isPlainObject(el)) {
for (var key in el) {
// Make sure the key is not part of the prototype chain
if (el.hasOwnProperty(key)) {
var value = el[key];
if (key == 'id') {
// If the key has been seen, remove it
if (seenIds[value]) {
delete el[key];
continue; // Skip further processing
} else seenIds[value] = true;
}
processData(value);
// If the child is now empty, remove it from the object
if (checkForEmpty(value)) delete el[key];
}
}
}
}

Categories

Resources