![](/img/trans.png)
[英]How to parse paginated JSON API response with complex nesting and unnamed array?
[英]How parse JSON with complex nesting and unnamed array?
我試圖弄清楚如何解析當我使用 vanilla javascript 調用特定數據庫(如下所示的 JSON 響應)時收到的 JSON 響應 - 到目前為止我還沒有運氣。 我正在向 Quickbase 數據庫發出 API 調用,它們的 JSON 響應具有標准格式。 我正在調用的 API 可以在此鏈接中找到: https://developer.quickbase.com/operation/runQuery 。
這是 API 調用的響應如下所示
{
"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
}
}
這就是我想要將其解析成的內容(不需要省略此處未顯示的 JSON - 為了清楚起見,我只是這樣做了)
{
"data": [
{
"Related Invoice":11.0,
"TEST1":"A",
"TEST2":"B"
},
{
"Related Invoice":11.0,
"TEST1":"C",
"TEST2":"D"
}
]
}
以下是我正在使用的完整 javascript 代碼
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));
這就是我想要實現的目標
|-----------------------------------------|
| Count | Related Invoice | TEST1 | TEST2 |
|-------|-----------------|-------|-------|
| 1 | 11.0 | A | B |
|-------|-----------------|-------|-------|
| 2 | 11.0 | C | D |
|-----------------------------------------|
我需要完成三件事:
"6", "69 and "70"
重命名為對應的字段。label( "Related Invoice", "TEST1" and "TEST2"
)。11.0, "A", "B", ...
),並將它們設置為上面#1 中所示對象的值。 例如,這將使6 (Related Invoice)
成為鍵,而11.0
成為值。如果您需要我澄清更多信息,請告訴我。
要以您正在查看的方式轉換數據,您需要循環 object 中的data
鍵,並根據循環結果創建一個新數組。
一種方法是使用Array.prototype.map()
。 有了這個,您可以遍歷數組中的每個項目並返回一個新值。
在這個 map 循環中,您將遍歷data
數組中的每個項目。 對於每個項目,您需要從fields
數組中獲取id
和label
,並使用該數組創建一個新的 object。 要在循環中創建新的 object,可以使用Array.prototype.reduce()
方法。
因此,在這種情況下,您將有一個嵌套循環。 內部循環將遍歷fields
數組並使用 id 從data
數組中獲取正確的值。 然后它返回一個 object 和label
和您要求的value
設置。 然后,周圍的map
方法將返回一個包含對象的新數組。 多多,魔法!
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.