解决JS调用TVMAZE API时的Cannot read property 'length' of null错误
解决JavaScript调用TVMAZE API时的
Cannot read property 'length' of null错误 你遇到的这个错误核心原因是fetch是异步操作,你的代码在还没拿到API返回数据的时候就已经执行了后面的DOM操作和循环逻辑,这时候foo还是初始的null,自然读不了length属性。下面一步步帮你修复问题,同时优化代码里的其他潜在问题:
错误原因详解
fetch方法是异步的,它不会阻塞后续代码执行:
- 你调用
fetch后,浏览器会在后台发起请求,同时继续执行后面的alert、var json_data = foo以及循环代码 - 这时候
then回调还没执行,foo依然是null,所以json_data.length就会抛出TypeError
完整修复方案
1. 把所有数据处理和DOM操作放到fetch的回调里
确保只有当API返回数据后,才开始渲染页面内容。
2. 修正表格行的HTML结构错误
你原来的每个<td>后面都加了</tr>,这会导致每个单元格都是单独的一行,完全破坏表格结构,要把所有单元格拼接完后再加一个</tr>。
3. 修正TVMAZE API的数据字段路径
TVMAZE的schedule/full接口返回的数据里,很多字段(比如name、image、language、country等)都嵌套在show对象里,不是直接在根层级,你原来的写法会拿到undefined。
4. 处理空值和特殊字段
比如image可能为null,直接显示会出[object Object],要做判断;summary包含HTML标签,直接插入需要用html()方法;genres是数组,要转成字符串。
修复后的JavaScript代码
fetch('http://api.tvmaze.com/schedule/full') .then(resp => resp.json()) .then(data => { // 拿到数据后再开始处理 const tbl = $("<table/>").attr("id", "mytable"); $("#div1").append(tbl); // 遍历每一条节目数据 data.forEach(item => { // 处理嵌套的show对象 const show = item.show; // 处理图片空值 const imageUrl = show.image ? show.image.medium : '无图片'; // 处理评分空值 const rating = show.rating ? show.rating.average : '暂无评分'; // 处理国家字段 const country = show.country ? show.country.name : '未知国家'; // 处理类型数组转字符串 const genres = show.genres.length ? show.genres.join(', ') : '无类型'; // 拼接完整的表格行 const tr = ` <tr> <td>${item.id}</td> <td>${show.name}</td> <td>${imageUrl}</td> <td>${item.airdate}</td> <td>${item.airtime}</td> <td>${item.airstamp}</td> <td>${item.runtime || '未知时长'}</td> <td>${item.season || '未知季数'}</td> <td>${show.language || '未知语言'}</td> <td>${genres}</td> <td>${country}</td> <td>${show.network ? show.network.code : '未知代码'}</td> <td>${show.network ? show.network.timezone : '未知时区'}</td> <td>${rating}</td> <td>${show.summary ? $(show.summary).text() : '暂无简介'}</td> </tr> `; $("#mytable").append(tr); }); }) .catch(err => { // 捕获请求错误,方便调试 console.error('请求API出错:', err); $("#div1").text('加载数据失败,请稍后重试'); });
修复后的HTML代码(基本不变,确保JS在DOM加载后执行)
<!DOCTYPE html> <html> <head> <title>TV Maze 节目表</title> <style> #mytable, td{ border:1px solid blue; border-collapse: collapse; } td { padding: 8px; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> </head> <body> <div id="div1"> </div> <!-- 把JS放在body末尾,确保DOM已经加载完成 --> <script src="tvmazeapi.js"></script> </body> </html>
额外优化点
- 加了
catch回调处理请求失败的情况,提升用户体验 - 对所有可能为空的字段做了默认值处理,避免显示
undefined - 优化了表格样式,添加了
border-collapse和内边距,让表格更美观 - 使用
forEach替代for循环,代码更简洁易读
内容的提问来源于stack exchange,提问作者Kunal
相关产品推荐
相关产品推荐

