Javascript 如何使用复杂嵌套和未命名数组解析分页JSON API响应?

Javascript 如何使用复杂嵌套和未命名数组解析分页JSON API响应?,javascript,json,pagination,quickbase,Javascript,Json,Pagination,Quickbase,我(在@EmielZuurbier的帮助下)构建了一个发票模板,该模板向Quickbase发出API调用。API响应被分页。如何将分页响应解析到单个表中 Quickbase API端点: Quickbase分页元数据说明: 下面是API调用的响应情况(我删除了数据下的大部分项目,否则在stackoverflow上发布会很长时间) { "data": [ { "15": {

我(在@EmielZuurbier的帮助下)构建了一个发票模板,该模板向Quickbase发出API调用。API响应被分页。如何将分页响应解析到单个表中

  • Quickbase API端点:
  • Quickbase分页元数据说明:
下面是API调用的响应情况(我删除了数据下的大部分项目,否则在stackoverflow上发布会很长时间)

{
    "data": [
        {
            "15": {
                "value": "F079427"
            },
            "19": {
                "value": 50.0
            },
            "48": {
                "value": "(S1)"
            },
            "50": {
                "value": "2021-03-01"
            },
            "8": {
                "value": "71 Wauregan Rd, Danielson, Connecticut 06239"
            }
        },
        {
            "15": {
                "value": "F079430"
            },
            "19": {
                "value": 50.0
            },
            "48": {
                "value": "(S1)"
            },
            "50": {
                "value": "2021-03-01"
            },
            "8": {
                "value": "7 County Home Road, Thompson, Connecticut 06277"
            }
        },
        {
            "15": {
                "value": "F079433"
            },
            "19": {
                "value": 50.0
            },
            "48": {
                "value": "(S1)"
            },
            "50": {
                "value": "2021-03-16"
            },
            "8": {
                "value": "12 Bentwood Street, Foxboro, Massachusetts 02035"
            }
        }
    ],
    "fields": [
        {
            "id": 15,
            "label": "Project Number",
            "type": "text"
        },
        {
            "id": 8,
            "label": "Property Adress",
            "type": "address"
        },
        {
            "id": 50,
            "label": "Date Completed",
            "type": "text"
        },
        {
            "id": 48,
            "label": "Billing Codes",
            "type": "text"
        },
        {
            "id": 19,
            "label": "Total Job Price",
            "type": "currency"
        }
    ],
    "metadata": {
        "numFields": 5,
        "numRecords": 500,
        "skip": 0,
        "totalRecords": 766
    }
}
下面是我正在使用的完整javascript代码

const urlParams = new URLSearchParams(window.location.search);
//const dbid = urlParams.get('dbid');//
//const fids = urlParams.get('fids');//
let rid = urlParams.get('rid');
//const sortLineItems1 = urlParams.get('sortLineItems1');//
//const sortLineItems2 = urlParams.get('sortLineItems2');//
let subtotalAmount = urlParams.get('subtotalAmount');
let discountAmount = urlParams.get('discountAmount');
let creditAmount = urlParams.get('creditAmount');
let paidAmount = urlParams.get('paidAmount');
let balanceAmount = urlParams.get('balanceAmount');
let clientName = urlParams.get('clientName');
let clientStreetAddress = urlParams.get('clientStreetAddress');
let clientCityStatePostal = urlParams.get('clientCityStatePostal');
let clientPhone = urlParams.get('clientPhone');
let invoiceNumber = urlParams.get('invoiceNumber');
let invoiceTerms = urlParams.get('invoiceTerms');
let invoiceDate = urlParams.get('invoiceDate');
let invoiceDueDate = urlParams.get('invoiceDueDate');
let invoiceNotes = urlParams.get('invoiceNotes');


const formatCurrencyUS = function (x) {
    return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(x);
}


let subtotalAmountFormatted = formatCurrencyUS(subtotalAmount);
let discountAmountFormatted = formatCurrencyUS(discountAmount);
let creditAmountFormatted = formatCurrencyUS(creditAmount);
let paidAmountFormatted = formatCurrencyUS(paidAmount);
let balanceAmountFormatted = formatCurrencyUS(balanceAmount);


document.getElementById("subtotalAmount").innerHTML = `${subtotalAmountFormatted}`;
document.getElementById("discountAmount").innerHTML = `${discountAmountFormatted}`;
document.getElementById("creditAmount").innerHTML = `${creditAmountFormatted}`;
document.getElementById("paidAmount").innerHTML = `${paidAmountFormatted}`;
document.getElementById("balanceAmount").innerHTML = `${balanceAmountFormatted}`;
document.getElementById("clientName").innerHTML = `${clientName}`;
document.getElementById("clientStreetAddress").innerHTML = `${clientStreetAddress}`;
document.getElementById("clientCityStatePostal").innerHTML = `${clientCityStatePostal}`;
document.getElementById("clientPhone").innerHTML = `${clientPhone}`;
document.getElementById("invoiceNumber").innerHTML = `${invoiceNumber}`;
document.getElementById("invoiceTerms").innerHTML = `${invoiceTerms}`;
document.getElementById("invoiceDate").innerHTML = `${invoiceDate}`;
document.getElementById("invoiceDueDate").innerHTML = `${invoiceDueDate}`;
document.getElementById("invoiceNotes").innerHTML = `${invoiceNotes}`;


let headers = {
    'QB-Realm-Hostname': 'XXXXX',
    'User-Agent': 'Invoice',
    'Authorization': 'XXXXX',
    'Content-Type': 'application/json'
}


let body =

{
    "from": "bq9dajvu5",
    "select": [
        15,
        8,
        50,
        48,
        19
    ],
    "where": `{25.EX.${rid}}`,
    "sortBy": [
        {
            "fieldId": 50,
            "order": "ASC"
        },
        {
            "fieldId": 8,
            "order": "ASC"
        }
    ],
    "options": {
        "skip": 0
    }
}


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);
        console.log(line_items);





        const transformResponseData = (line_items) => {
            const { data, fields } = line_items;

            //***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 {
                ...line_items,
                data: revivedData
            };
        };





        const createTable = ({ data, fields }) => {
            const table = document.getElementById('line_items');                //const table = document.createElement('table'); 
            const tHead = document.getElementById('line_items_thead');      //const tHead = table.createTHead();
            const tBody = document.getElementById('line_items_tbody');      //const tBody = table.createTBody();
            //***Create a head for each label in the fields array***//
            const tHeadRow = tHead.insertRow();



            // ***Create the counts cell manually***//
            const tHeadRowCountCell = document.createElement('th');
            tHeadRowCountCell.textContent = 'Count';
            tHeadRow.append(tHeadRowCountCell);



            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 === 5 ?
                        Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value) ://value.toFixed(2) :
                        value;


                }
            }
            return table;
        };





        const data = transformResponseData(line_items);
        const table = createTable(data);
        document.getElementById("line_items_div").append(table)                 //.innerHTML = table <-- this does not work//       //document.body.append(table); 
        console.log(data);





    }
};

xmlHttp.send(JSON.stringify(body));
const urlparms=新的URLSearchParams(window.location.search);
//const dbid=urlParams.get('dbid')//
//const fids=urlParams.get('fids')//
让rid=urlparms.get('rid');
//const sortLineItems1=urlParams.get('sortLineItems1')//
//const sortLineItems2=urlParams.get('sortLineItems2')//
让subtotalAmount=urlParams.get('subtotalAmount');
让deffentamount=urlParams.get('deffentamount');
让creditAmount=urlParams.get('creditAmount');
让paidAmount=urlParams.get('paidAmount');
让balanceAmount=urlparms.get('balanceAmount');
让clientName=urlParams.get('clientName');
让clientStreetAddress=urlParams.get('clientStreetAddress');
让clientCityStatePostal=urlParams.get('clientCityStatePostal');
让clientPhone=urlParams.get('clientPhone');
让invoiceNumber=urlParams.get('invoiceNumber');
让invoiceTerms=urlParams.get('invoiceTerms');
让invoiceDate=urlParams.get('invoiceDate');
让invoiceDueDate=urlParams.get('invoiceDueDate');
让invoiceNotes=urlParams.get('invoiceNotes');
const formatCurrencyUS=函数(x){
返回新的Intl.NumberFormat('en-US',{style:'currency',currency:'USD'});
}
让小计金额格式化=格式货币(小计金额);
设DeffentAmountFormatted=FormatCurrencyCus(DeffentAmount);
设creditAmountFormatted=FormatCurrencyCus(creditAmount);
设paidAmountFormatted=formatCurrencyUS(paidAmount);
让balanceAmountFormatted=格式货币(balanceAmount);
document.getElementById(“小计金额”).innerHTML=`${subtotalAmountFormatted}`;
document.getElementById(“discountAmount”).innerHTML=`${discountAmountFormatted}`;
document.getElementById(“creditAmount”).innerHTML=`${creditAmountFormatted}`;
document.getElementById(“paidAmount”).innerHTML=`${paidAmountFormatted}`;
document.getElementById(“balanceAmount”).innerHTML=`${balanceAmountFormatted}`;
document.getElementById(“clientName”).innerHTML=`${clientName}`;
document.getElementById(“clientStreetAddress”).innerHTML=`${clientStreetAddress}`;
document.getElementById(“clientCityStatePostal”).innerHTML=`${clientCityStatePostal}`;
document.getElementById(“clientPhone”).innerHTML=`${clientPhone}`;
document.getElementById(“invoiceNumber”).innerHTML=`${invoiceNumber}`;
document.getElementById(“invoiceTerms”).innerHTML=`${invoiceTerms}`;
document.getElementById(“invoiceDate”).innerHTML=`${invoiceDate}`;
document.getElementById(“invoiceDueDate”).innerHTML=`${invoiceDueDate}`;
document.getElementById(“invoiceNotes”).innerHTML=`${invoiceNotes}`;
让标题={
“QB领域主机名”:“XXXXX”,
“用户代理”:“发票”,
“授权”:“XXXXX”,
“内容类型”:“应用程序/json”
}
让身体=
{
“发件人”:“bq9dajvu5”,
“选择”:[
15,
8.
50,
48,
19
],
“where”:“{25.EX.${rid}}”,
“肮脏的”:[
{
“fieldId”:50,
“订单”:“ASC”
},
{
“字段ID”:8,
“订单”:“ASC”
}
],
“选择”:{
“跳过”:0
}
}
const xmlHttp=new XMLHttpRequest();
xmlHttp.open('POST','https://api.quickbase.com/v1/records/query",对),;
for(头中的常量键){
setRequestHeader(key,headers[key]);
}
xmlHttp.onreadystatechange=函数(){
if(xmlHttp.readyState==XMLHttpRequest.DONE){
log(xmlHttp.responseText);
让line_items=JSON.parse(this.responseText);
控制台日志(第_行项目);
const transformResponseData=(行项目)=>{
const{data,fields}=行项目;
//***基于数据和字段数组的值返回包含对象的新数组***//
const revivedData=data.map(条目=>
reduce((对象,{id,label})=>{
对象[label]=条目[id]。值;
返回对象;
}, {})
);
//***将原始对象与新数据键组合***//
返回{
…行项目,
数据:revivedData
};
};
const createTable=({data,fields})=>{
const table=document.getElementById('line_items');//const table=document.createElement('table');
const tHead=document.getElementById('line_items_tHead');//const tHead=table.createTHead();
const tBody=document.getElementById('line_items_tBody');//const tBody=table.createTBody();
//***为字段数组中的每个标签创建标头***//
const tHeadRow=tHead.insertRow();
//***手动创建计数单元格***//
const tHeadRowCountCell=document.createElement('th');
tHeadRowCountCell.textContent='Count';
tHeadRow.append(tHeadRowCountCell);
for(字段的常量{label}){
const tHeadRowCell=document.createElement('th');
tHeadRowCell.textContent=标签;
tHeadRow.append(tHeadRowCell);
}
//输出新数据数组的所有值//
for(data.entries()的常量[索引,条目]){
const tBodyRow=tBody.insertRow();
//使用对象中的索引和值创建一个新数组//
常数v
// Select the table div element.
const tableDiv = document.getElementById('line_items_div');

// Get the records, collect them in multiple requests, and generate a table from the data.
collectRecords().then(records => {
  const data = transformRecordsData(records);
  const table = createTable(data);
  tableDiv.append(table);
});