API数据渲染表格出现Uncaught TypeError错误求助
问题描述
从API读取数据并渲染表格,脚本功能正常,但控制台出现错误:Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'innerText'),其中一处代码有红色下划线标注。
HTML代码
<div class="rebeltable"> <table id="rebeltable"> <thead> <td class="col-span-1">nome</td> <td class="col-span-1">cognome</td> <td class="col-span-1">data di nascita</td> <td class="col-span-1">email</td> <td class="col-span-1">qualifica</td> <td class="col-span-1">username</td> <td class="col-span-1">password</td> </thead> <tbody> </tbody> </table> </div>
JavaScript代码
const tabella = document.getElementById('rebeltable') const tbody = tabella.getElementsByTagName('tbody')[0] const tdhead = tabella.getElementsByTagName('thead')[0].childNodes[1].children async function getUser(url){ const response = await fetch(url) const resolve = await response.json() createTable(resolve) // 控制台第一个未下划线标注的错误 } getUser('https://random-data-api.com/api/v2/users?size=10&response_type=json') function createTable(data) { let tabellaDati = [] let tabellaGriglia = [] const asseX = tdhead.length const asseY = data.length for(let i=0; i<data.length; i++) { let nome = data[i].first_name let cognome = data[i].last_name let dataNascita = data[i].date_of_birth let email = data[i].email let qualifica = data[i].employment.title let userName = data[i].username let password = data[i].password tabellaDati.push([[nome, cognome, dataNascita, email, qualifica, userName, password]]) const riga = document.createElement('tr') tabellaGriglia.push(riga) // 插入与"data"中记录数量相同的空行 for(k=0; k<tdhead.length; k++) { // tdhead.length是列数,即7 const cella = document.createElement('td') riga.appendChild(cella) } tbody.appendChild(riga) }; // console.log(tabellaDati); const singleCell = tbody.getElementsByTagName("td"); for (let index = 0; index < asseY; index++) { singleCell[7*index].innerText = tabellaDati[index][0][0] for (let k = 1; k < asseY; k++) { singleCell[(7*index)+k].innerText = tabellaDati[index][0][k] // 这里是第二个错误,tabellaDati[index][0][k]被红色下划线标注 } } }
控制台报错信息
Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'innerText') at createTable (app.js:62:43) at getUser (app.js:17:5) createTable @ app.js:62 getUser @ app.js:17 await in getUser (asinc) (anonimo) @ app.js:19
问题排查与修复
错误原因分析
- 内层循环边界错误:内层循环条件
k < asseY逻辑错误,asseY是数据行数(10),但每一行只有7列数据。当k >=7时,tabellaDati[index][0][k]会变成undefined,同时singleCell[(7*index)+k]也会超出当前行的单元格范围,导致设置innerText时触发Cannot set properties of undefined错误。 - 不必要的嵌套数组:
tabellaDati.push([[nome, ...]])创建了三层嵌套数组,结构冗余,增加了代码复杂度和出错概率。 - DOM节点依赖风险:
tabella.getElementsByTagName('thead')[0].childNodes[1]依赖HTML中的空白文本节点,一旦HTML结构调整(比如去掉换行),这段代码会直接失效。
修复后的代码
优化后的JavaScript
const tabella = document.getElementById('rebeltable') const tbody = tabella.getElementsByTagName('tbody')[0] // 直接获取thead下的所有td元素,避免依赖空白文本节点 const tdhead = tabella.querySelector('thead').children async function getUser(url){ try { const response = await fetch(url) const resolve = await response.json() createTable(resolve) } catch (err) { console.error('数据获取失败:', err) } } getUser('https://random-data-api.com/api/v2/users?size=10&response_type=json') function createTable(data) { const tabellaDati = [] const colCount = tdhead.length // 列数固定为7 for(let i=0; i<data.length; i++) { const user = data[i] // 简化为二维数组,直接存储每一行的数据 tabellaDati.push([ user.first_name, user.last_name, user.date_of_birth, user.email, user.employment.title, user.username, user.password ]) const riga = document.createElement('tr') for(let k=0; k<colCount; k++) { const cella = document.createElement('td') // 创建单元格时直接赋值,避免后续遍历查找 cella.innerText = tabellaDati[i][k] riga.appendChild(cella) } tbody.appendChild(riga) } }
修复说明
- 修正循环逻辑:去掉了后续单独遍历单元格的冗余代码,改为创建单元格时直接赋值,从根源避免越界问题。
- 简化数组结构:将
tabellaDati改为二维数组,结构更清晰,减少访问层级。 - 优化DOM获取:用
querySelector('thead').children替代childNodes[1],避免空白文本节点带来的潜在问题。 - 添加错误捕获:在
getUser函数中加入try/catch,处理API请求失败的情况,避免未捕获的Promise错误。
内容的提问来源于stack exchange,提问作者Fabio Giacomini
相关产品推荐
相关产品推荐

