调用Flask API向Chart.js传数据时报searchResults.filter is not a function错误
错误触发原因
- 时序逻辑错误:当前
setTimeout写在d3.json的then回调外部,请求发出后立刻开始计时50ms,而非等待API请求响应完成后再计时。若API响应耗时超过50ms,init执行时searchResults还未被正确赋值;如果请求失败,searchResults会一直停留在初始值或被赋值为非数组类型。 - 数据类型不匹配:
filter是数组专属方法,报错说明init执行时searchResults不是数组。大概率是Flask接口返回的JSON结构不符合预期,比如返回了外层包裹的对象(如{"data": [xxx], "code": 200})而非直接返回数组,导致chart_data本身不是数组,赋值给searchResults后调用filter失败。 setTimeout本身是不可靠的延迟方案,网络波动、后端响应速度变化都可能导致超时时间设置失效。
修复方案
- 废弃
setTimeout方案,将init调用移至d3.json的then回调内部,确保只有API请求成功拿到数据后才执行初始化逻辑。 - 拿到返回数据后先做类型校验,确认是数组后再赋值,若接口返回的是外层包裹的对象,要取出对应数组字段再赋值。
- 添加请求异常捕获逻辑,方便定位接口报错问题。
修改后代码示例
API请求部分
var queryUrl = "http://127.0.0.1:5000/api/1/GenderOverTime"; var searchResults = []; d3.json(queryUrl) .then(function (chart_data) { // 可先在控制台查看返回结构,确认是否为数组 console.log('接口返回数据:', chart_data, Array.isArray(chart_data)) // 若接口直接返回数组直接赋值即可;若返回的是外层包裹对象,需取出对应数组字段,例:searchResults = chart_data.data searchResults = chart_data; // 拿到数据后再执行初始化 init(); }) .catch(function(error){ // 捕获请求异常,方便定位问题 console.error('API请求失败:', error) })
init函数部分(可选优化)
function init(){ // 增加类型校验,避免非数组时报错 if(!Array.isArray(searchResults)) { console.error('searchResults不是合法数组,当前值:', searchResults) return } console.log("searchResults: ", searchResults); let selector = d3.select("#selDataset"); let options = [] filtered_data_for_chart = searchResults.filter(result=>{ if (!options.includes(result.Sport)){ options.push(result.Sport) selector .append("option") .text(result.Sport) .property("value", result.Sport); } return result.Sport==="Gymnastics" }); // 剩余原有逻辑保持不变 }
内容的提问来源于stack exchange,提问作者sak0213
相关产品推荐
相关产品推荐

