I am trying to figure out how to parse the JSON response I receive when I make a call to a specific database (JSON response shown below) using vanilla javascript - and so far I have not had any luck. I am placing an API call to the Quickbase database and they have a standard formatting for their JSON response. The API i am calling can be found at this link: https://developer.quickbase.com/operation/runQuery.
Here is what a response from the API call looks like
{
"data": [
{
"6": {
"value": 11.0
},
"69": {
"value": "A"
},
"70": {
"value": "B"
}
},
{
"6": {
"value": 11.0
},
"69": {
"value": "C"
},
"70": {
"value": "D"
}
}
],
"fields": [
{
"id": 6,
"label": "Related Invoice",
"type": "numeric"
},
{
"id": 69,
"label": "TEST1",
"type": "text"
},
{
"id": 70,
"label": "TEST2",
"type": "text"
}
],
"metadata": {
"numFields": 3,
"numRecords": 2,
"skip": 0,
"totalRecords": 2
}
}
And this is what I want to parse it into (do NOT need to omit the JSON not shown here - I just did that for clarity)
{
"data": [
{
"Related Invoice":11.0,
"TEST1":"A",
"TEST2":"B"
},
{
"Related Invoice":11.0,
"TEST1":"C",
"TEST2":"D"
}
]
}
Below is the full javascript code i am using
let headers = {
'QB-Realm-Hostname': 'XXXXXX',
'User-Agent': 'Invoice',
'Authorization': 'XXXXXX',
'Content-Type': 'application/json'
}
let body =
{
"from": "bq2paydp2",
"select": [
6,
69,
70
],
"where": "{6.EX.11}",
"sortBy": [
{
"fieldId": 6,
"order": "ASC"
},
{
"fieldId": 69,
"order": "ASC"
}
]
}
const xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST', 'https://api.quickbase.com/v1/records/query', true);
for (const key in headers) {
xmlHttp.setRequestHeader(key, headers[key]);
}
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === XMLHttpRequest.DONE) {
console.log(xmlHttp.responseText);
let line_items = JSON.parse(this.responseText, dataReviver);
console.log(line_items);
//function dataReviver (key, value) {
//if (key = 6)
// {
// var newHeaderName = 99;
// return newHeaderName;
// }
//
// return value;
//}
//document.getElementById('abc').innerHTML = line_items.data[0][6].value;
function generateTableHead(table,tableData) {
let thead = table.createTHead();
let row = thead.insertRow();
for (let key of tableData) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
};
function generateTable(table, tableData) {
for (let element of tableData) {
let row = table.insertRow();
for (key in element) {
let cell = row.insertCell();
let text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
};
let table = document.querySelector("table");
let tableData = Object.keys(line_items.data[0]);
generateTableHead(table, tableData);
generateTable(table, line_items.data);
}
};
xmlHttp.send(JSON.stringify(body));
This is what I am trying to achieve
|-----------------------------------------|
| Count | Related Invoice | TEST1 | TEST2 |
|-------|-----------------|-------|-------|
| 1 | 11.0 | A | B |
|-------|-----------------|-------|-------|
| 2 | 11.0 | C | D |
|-----------------------------------------|
I need to accomplish 3 things:
#1 Rename "6", "69 and "70" to the corresponding fields.label ( "Related Invoice", "TEST1" and "TEST2" ).
#2 Take the value of the objects nested under the objects shown above in #1 ( 11.0, "A", "B", ... ) and set them as the value of the objects shown in #1 above. This would, for example, make 6 (Related Invoice) the key and 11.0 the value.
#3 I ultimately want to display this in a table on a webpage. the html and css I can handle its the Javascript and JSON that I am not that great with.
If you need me to clarify anymore information please let me know.
To transform the data in the way you're looking, you'll need to loop over the data key in the object and create a new array based on the result of the loop.
A way to do this is with Array.prototype.map(). With this you can loop over each item in the array and return a new value.
In this map loop you are looping over each item in the data array. For each item you'll want to get the id and label from the fields array and use that array to create a new object. To create a new object within in a loop, you could use the Array.prototype.reduce() method.
So in this case you'll have a nested loop. The inner loop will loop over the fields array and uses the id to get the correct value from data array. It then returns an object with the label and the value set like you requested. The surrounding map method will then return a new array with objects. Tadaa, magic!
const response = {
"data": [{
"6": {
"value": 11.0
},
"69": {
"value": "A"
},
"70": {
"value": "B"
}
},
{
"6": {
"value": 11.0
},
"69": {
"value": "C"
},
"70": {
"value": "D"
}
}
],
"fields": [{
"id": 6,
"label": "Related Invoice",
"type": "numeric"
},
{
"id": 69,
"label": "TEST1",
"type": "text"
},
{
"id": 70,
"label": "TEST2",
"type": "text"
}
],
"metadata": {
"numFields": 3,
"numRecords": 2,
"skip": 0,
"totalRecords": 2
}
};
const transformResponseData = (response) => {
const { data, fields } = response;
// Return a new array with objects based on the values
// of the data and fields arrays.
const revivedData = data.map(entry =>
fields.reduce((object, { id, label }) => {
object[label] = entry[id].value;
return object;
}, {})
);
// Combine the original object with the new data key.
return {
...response,
data: revivedData
};
};
const createTable = ({ data, fields }) => {
const table = document.createElement('table');
const tHead = table.createTHead();
const tBody = table.createTBody();
const tHeadRow = tHead.insertRow();
// Create the counts cell manually.
const tHeadRowCountCell = document.createElement('th');
tHeadRowCountCell.textContent = 'Count';
tHeadRow.append(tHeadRowCountCell);
// Create a head for each label in the fields array.
for (const { label } of fields) {
const tHeadRowCell = document.createElement('th');
tHeadRowCell.textContent = label;
tHeadRow.append(tHeadRowCell);
}
// Output all the values of the new data array.
for (const [index, entry] of data.entries()) {
const tBodyRow = tBody.insertRow();
// Create a new array with the index and the
// values from the object.
const values = [
index + 1,
...Object.values(entry)
];
// Loop over the combined values array.
for (const [index, value] of values.entries()) {
const tBodyCell = tBodyRow.insertCell();
tBodyCell.textContent = index === 1 ?
value.toFixed(1) :
value;
}
}
return table;
};
const data = transformResponseData(response);
const table = createTable(data);
document.body.append(table);
Related
I'm importing data from my crm Pipedrive into Google sheets using Google Apps Script. This is part of a larger process but I'm at an impasse with this section of the script. I need to return a value by matching two parts of one array to another array.
First I pull all deal fields, which returns custom field keys and their id/label pairs. Here's a simplified output example:
{
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "Sale",
"id": 29
},
{
"label": "Rent",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
}
Then I have separate info from a specific deal that includes an id. I need to match the below id 28 to the above array and return the label Expired:
var leadType = dealresponse.data["c4ecbe01c34994ede3a50c0f8"];
which returns 28
I don't know what '28' means so that's why I need to match it to the label Expired.
The dealFields array is long, maybe 50 or 100 of the above array objects. And there are around 10 custom deal field keys where I will have to return the label base on matching the key and id. I think I have to loop each key and id to return the label. But not sure of the optimum way to do this and save on processing power.
I tried:
for (var i in dealFieldsresponse) {
if (dealFieldsresponse[i].data.key == "c4ecbe01c34994ede3a50c0f8") {
for (var j in dealFieldsresponse[j]) {
if (dealFieldsresponse[j].id == "28") {
Logger.log(dealFieldsresponse[j].label);
}
}
}
}
It's not working. I'm new at javascript and programming in general so this is my best guess and I appreciate any insights.
Edit: here's a bigger chunk of code that I have to work with:
// Get deal fields data
var dealFieldsurl = URL +'/v1/dealFields?api_token='+ API_TOKEN;
var options = {
"method": "get",
"contentType": "application/json",
};
var dealFieldsresponse = UrlFetchApp.fetch(dealFieldsurl, options);
dealFieldsresponse = JSON.parse(dealFieldsresponse.getContentText());
// Get deal data
var dealurl = URL +'/v1/deals/' + dealId + '?api_token='+ API_TOKEN;
var options = {
"method": "get",
"contentType": "application/json",
};
var dealresponse = UrlFetchApp.fetch(dealurl, options);
dealresponse = JSON.parse(dealresponse.getContentText());
var propertyAddress = dealresponse.data["9bd1d8c4f07f5795fd8bffb16f3b63c6547d7d3a"];
var leadType = dealresponse.data["c4ecbe01c3494d1be52432f4a3194ede3a50c0f8"];
var dealType = dealresponse.data["a4269fb4730cf7fd1787752be94eacbc4b0de24e"];
var dealSource = dealresponse.data["d76fa2d6f8454a51f7d64d981cd9320877bc2ea0"];
var marketingFor = dealresponse.data["58cb55090b55652b7f89a8b44074682d874c548a"];
var dateListedOnMarket = dealresponse.data["aa49c7b95a7d151bec4c2d936f6ab40d0caea43c"];
var dateTakenOffMarket = dealresponse.data["660c1250b0a641a10ff9121c2df124ff89c13052"];
var askingPrice = dealresponse.data["1de94dbf589fda7a3a3248662cd24f03d512a961"];
And the dealFieldsresponse variable stores an array with many objects containing arrays. Here are two primary objects, as you can see each has a key and then options. I need to match the key and then find the id within options for each key
{
"id": 12500,
"key": "c4ecbe01c3494d1be52432f4a3194ede3a50c0f8",
"name": "Lead Type",
"order_nr": 64,
"field_type": "set",
"add_time": "2020-08-20 19:33:22",
"update_time": "2020-08-20 19:33:22",
"last_updated_by_user_id": 11678191,
"active_flag": true,
"edit_flag": true,
"index_visible_flag": true,
"details_visible_flag": true,
"add_visible_flag": true,
"important_flag": true,
"bulk_edit_allowed": true,
"searchable_flag": false,
"filtering_allowed": true,
"sortable_flag": true,
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "Sale",
"id": 29
},
{
"label": "Rent",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
},
{
"id": 12502,
"key": "a4269fb4730cf7fd1787752be94eacbc4b0de24e",
"name": "Deal Type",
"order_nr": 65,
"field_type": "set",
"add_time": "2020-08-20 19:57:12",
"update_time": "2020-08-20 19:57:12",
"last_updated_by_user_id": 11678191,
"active_flag": true,
"edit_flag": true,
"index_visible_flag": true,
"details_visible_flag": true,
"add_visible_flag": true,
"important_flag": true,
"bulk_edit_allowed": true,
"searchable_flag": false,
"filtering_allowed": true,
"sortable_flag": true,
"options": [
{
"label": "Lease",
"id": 37
},
{
"label": "Financing",
"id": 38
},
{
"label": "Assign",
"id": 39
},
{
"label": "ST",
"id": 40
},
{
"label": "Other (see notes)",
"id": 41
}
],
"mandatory_flag": false
},
Edit 2: how do I return the labels for multiple ids?
const obj = {
"a4269fb4730cf7fd1787752be94eacbc4b0de24e": {id: 37,38}, "58cb55090b55652b7f89a8b44074682d874c548a": {id: 44,45},
"2ec54cce0d091b69b1fd1a245c7aad02b57cadb8": {id: 126},
"fab84c732295022ecd7bdf58892a62cb4d8ecf24": {id: 50,52,54},
};
For example, I'd want the first to return red, blue as a string, and the second to return green, orange as a string. Assuming the labels that match the ids are colors. The third one only has one id, but the fourth one has three. How do I account for this? And I'd like my output to be some kind of array where I can then say search key a4269fb4730cf7fd1787752be94eacbc4b0de24e and return value red, blue as a string
I believe your goal as follows.
You want to retrieve the value of label using key and id from the JSON object in your question using Google Apps Script.
As a sample situation, you want to retrieve the value of "label": "Expired" using "key": "c4ecbe01c34994ede3a50c0f8" and "id": 28.
The JSON object has the arrays of data and options. Both arrays have the several elements.
Modification points:
If dealFieldsresponse is the JSON object in your question, dealFieldsresponse.data and dealFieldsresponse.data[].options are 1 dimensional array. When you want to retrieve the value of key and id, it is required to loop those arrays.
When above points are reflected to your script, it becomes as follows.
Modified script:
const searchKey = "c4ecbe01c34994ede3a50c0f8"; // Please set the value of key.
const searchId = 28; // Please set the value of id.
const dealFieldsresponse = {
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "FSBO",
"id": 29
},
{
"label": "FRBO",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
};
const data = dealFieldsresponse.data;
for (let i = 0; i < data.length; i++) {
if (data[i].key == searchKey) {
const options = data[i].options;
for (let j = 0; j < options.length; j++) {
if (options[j].id.toString() == searchId.toString()) {
// Logger.log(options[j].label);
console.log(options[j].label);
}
}
}
}
Other sample:
As other sample script, how about the following script? In this sample, the result values are put in an array.
const searchKey = "c4ecbe01c34994ede3a50c0f8"; // Please set the value of key.
const searchId = 28; // Please set the value of id.
const dealFieldsresponse = {
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "FSBO",
"id": 29
},
{
"label": "FRBO",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
};
const res = dealFieldsresponse.data.reduce((ar, {key, options}) => {
if (key == searchKey) {
options.forEach(({id, label}) => {
if (id == searchId) ar.push(label);
});
}
return ar;
}, []);
console.log(res)
Added:
When you want to retrieve the multiple values using the multiple key and id, how about the following sample script? In this sample script, the key c4ecbe01c34994ede3a50c0f8 and id 28 and the key a4269fb4730cf7fd1787752be94eacbc4b0de24e and id 37 are searched and the values of label are retrieved.
const obj = {
"c4ecbe01c34994ede3a50c0f8": {id: 28},
"a4269fb4730cf7fd1787752be94eacbc4b0de24e": {id: 37}
}; // Please set the key and id you want to search.
const dealFieldsresponse = {
"success": true,
"data": [
{
"id": 12500,
"key": "c4ecbe01c34994ede3a50c0f8",
"name": "Lead Type",
"options": [
{
"label": "Expired",
"id": 28
},
{
"label": "FSBO",
"id": 29
},
{
"label": "FRBO",
"id": 30
},
{
"label": "Other",
"id": 31
}
],
"mandatory_flag": false
}
]
};
dealFieldsresponse.data.forEach(({key, options}) => {
if (obj[key]) {
options.forEach(({id, label}) => {
if (id == obj[key].id) obj[key].label = label;
});
}
});
console.log(obj)
Result:
When above script is run, the following result is obtained.
{
"c4ecbe01c34994ede3a50c0f8":{"id":28,"label":"Expired"},
"a4269fb4730cf7fd1787752be94eacbc4b0de24e":{"id":37}
}
At above sample JSON object, the label of the key c4ecbe01c34994ede3a50c0f8 and id 28 is retrieved.
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)
I can't set up an algo that counts my occurrences while respecting ESlint's 6 standards in javascript.
My input table is :
[
{
"id": 2,
"name": "Health",
"color": "0190fe"
},
{
"id": 3,
"name": "Agriculture",
"color": "0190fe"
},
{
"id": 1,
"name": "Urban planning",
"color": "0190fe"
},
{
"id": 1,
"name": "Urban planning",
"color": "0190fe"
}
]
And i want to get :
{"Urban planning": 2, "Health": 1, ...}
But that does not work with ESLINT / REACT compilation...
This is my code :
const jsonToIterate = *'MyPreviousInputJson'*
const names = []
jsonToIterate.map(item => (names.push(item.name)))
const count = []
names.forEach(item => {
if (count[item]){
count.push({text: item, value: 1})
} else {
count.forEach(function(top){top.text === item ? top.value =+ 1 : null})
}
})
Thank you so much
Well, you want an object in the end, not an array, so count should be {}. I also wouldn't use map if you're not actually returning anything from the call. You can use reduce for this:
let counts = topicsSort.reduce((p, c, i, a) => {
if (!p.hasOwnProperty(c.name)) p[c.name] = 0;
p[c.name]++;
return p;
}, {});
I'm half exppecting someone to close this as a duplicate because all you've asked for is a frequency counter. But here's an answer anyway:
const jsonToIterate = *'MyPreviousInputJson'*;
const names = {};
jsonToIterate.map(obj => {
if(obj.name in names){
names[obj.name]++
}
else{
names[obj.name] = 1;
}
})
I have a json getting from API and store it into this.state.data like :
[
{
"name": "Primary Category",
"value": [
{
"value": "Fracture",
"Diagnosis_Code": ["DIAG003"],
"name": "Primary Category",
"FK_Diagnosis_Content_ID": 3,
"FK_Diagnosis_Category_ID": 1
},
{
"value": "Osteoarthritis",
"Diagnosis_Code": ["DIAG001"],
"name": "Primary Category",
"FK_Diagnosis_Content_ID": 1,
"FK_Diagnosis_Category_ID": 1
},
{
"value": "Osteonecrosis",
"Diagnosis_Code": ["DIAG002", "DIAG004"],
"name": "Primary Category",
"FK_Diagnosis_Content_ID": 2,
"FK_Diagnosis_Category_ID": 1
},
]
},
{
"name": "Anatomy",
"value": [
{
"value": "Hip",
"Diagnosis_Code": ["DIAG001"],
"name": "Anatomy",
"FK_Diagnosis_Content_ID": 4,
"FK_Diagnosis_Category_ID": 2
},
{
"value": "Pelvis",
"Diagnosis_Code": ["DIAG002", "DIAG003", "DIAG004"],
"name": "Anatomy",
"FK_Diagnosis_Content_ID": 6,
"FK_Diagnosis_Category_ID": 2
}
]
}
]
and I have a dynamic state using a function like this:
onChangeTextPress(key, value){
this.state.selected[key] = value
//another code
}
the example of this.state.selected is
[ 'Primary Category': 'Fracture', Anatomy: 'Hip']
I want to get FK_Diagnosis_Content_ID json depending on which this.state.selected[key] and it's value filled
so depending of selected example, I will have a result: [3, 4]
because json have a key called name and the value is Primary Category, and the value of selected state Primary Category is Fracture so I have a value of FK_Diagnosis_Content_ID in json, likewise about the Anatomy: 'Hip'
I don't know if you all know what I want, but feel free to asking me if you need another information,
hope someone can help me
You can get use of Object.keys() and Array.prototype.includes().
Sample 1
// Let's assume you have the below structure
const data = { 'Primary Category': 'Fracture', Anatomy: 'Hip' }
Object.keys(data).forEach((key) => console.log(key))
// Output:
// Primary Category
// Anatomy
So to get the desired value you can use something like below
Sample 2
// this.state.selected => { 'Primary Category': 'Fracture', Anatomy: 'Hip' }
const keys = Object.keys(this.state.selected);
const result = [];
this.state.data.forEach((d) => {
if(keys.includes(d.name)) {
d.value.forEach((v) => {
if(v.value === this.state.selected[d.name]) {
result.push(v['FK_Diagnosis_Content_ID']);
}
})
}
});
console.log(result);
// Output: [3,4]
Sample 3
// this.state.selected => [{ 'Primary Category': 'Fracture'}, {Anatomy: 'Hip' }]
// Since we know there is only one key in every object
const keys = this.state.selected.map((s) => Object.keys(s)[0])
const result = [];
this.state.data.forEach((d) => {
if(keys.includes(d.name)) {
d.value.forEach((v) => {
if(v.value === this.state.selected[keys.indexOf(d.name)][d.name]) {
result.push(v['FK_Diagnosis_Content_ID']);
}
})
}
});
console.log(result);
// Output: [3,4]
You can use this just as
const key = Object.keys(this.state.selected);
const response = [];
this.state.data.forEach((d) => {
if(key.includes(d.tag)) {
d.value.forEach((v) => {
if(v.value === this.state.selected[d.name]) {
result.push(v['FK_Diagnosis_Content_ID']);
}
})
}
});
console.log(result);
I have an existing array with multiple object. With an interval I would like to update the existing array with values from another array. See the (simplified) example below.
I've serverall gools:
Copy the value of fan_count form the new array, to the current array with the key "fan_count_new"
If a object is removed or added in the New array, it have to do the same to the Current array.
As far I can see now, I can use some es6 functions :) like:
object-assign, but how to set the new key "fan_count_new"?
How to loop through the array to compare and add or remove + copy the fan_count?
Current array:
[{
"fan_count": 1234,
"id": "1234567890",
"picture": {
"data": {
"url": "https://scontent.xx.fbcdn.net/v/photo.png"
}
}
},
{
"fan_count": 4321,
"id": "09876543210",
"picture": {
"data": {
"url": "https://scontent.xx.fbcdn.net/v/photo.png"
}
}
}, ...
]
New array:
[{
"fan_count": 1239,
"picture": {
"data": {
"url": "https://scontent.xx.fbcdn.net/v/photo.png"
}
"id": "1234567890"
},
{
"fan_count": 4329,
"picture": {
"data": {
"url": "https://scontent.xx.fbcdn.net/v/photo.png"
}
},
"id": "09876543210"
}, ...
]]
You can remove elements which doesn't exists in new array by using array.filter and you can loop through the new array to update the same object in the current array:
var currArr = [
{
"fan_count": 1234,
"id": "1234567890",
},
{
"fan_count": 4321,
"id": "09876543210",
},
{
"fan_count": 4321,
"id": "09876543215",
}
];
var newArr = [
{
"fan_count": 1234,
"id": "1234567890"
},
{
"fan_count": 5555,
"id": "09876543210"
}
];
currArr = currArr.filter(obj => newArr.some(el => el.id === obj.id));
newArr.forEach(obj => {
var found = currArr.find(o => o.id === obj.id);
if (found) {
found.fan_count_new = obj.fan_count;
}
});
console.log(currArr);
Later on I realised that is was better to turn it around, add the fan_count form the currArr to the new one. This because it is easier to handle new objects, and you dont't have to deal with deleted objects. So, anybody how is looking for something like this:
newArr.forEach(obj => {
var found = currArr.find(o => o.id === obj.id);
if (found) {
console.log('found: ', found.fan_count, obj.fan_count)
obj.fan_count_prev = found.fan_count;
obj.fan_count_diff = Math.round(obj.fan_count - found.fan_count);
}
if (typeof obj.fan_count_prev === "undefined") {
obj.fan_count_prev = obj.fan_count;
obj.fan_count_diff = 0
}
});