You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

空气质量API出现Uncaught (in promise) TypeError错误,求解决方案

问题:API返回数据缺失导致「Cannot read properties of undefined (reading 'v')」错误

我正在使用空气质量指数(AQI)API实现用户搜索城市获取对应空气质量数据的功能,但部分城市的API返回数据缺少部分监测指标(如臭氧浓度),导致代码执行时出现「Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'v')」错误,相关代码如下:

function retrieveAirQuality(topResultUrl) {
    var airQualityAPIUrl = "http://api.waqi.info/feed/"+topResultUrl+"/?token="+airQualityAPIToken;

    fetch(airQualityAPIUrl)
    .then(function(response) {
        return response.json();
    })
    .then(function(data) {
        if(data.status === "ok") {
            // Saves air quality results to variable
            var airQualityResult = {
                aqi: data.data.aqi,
                name: data.data.city.name,
                iaqi: data.data.iaqi,
                date: data.data.time
            }

            renderAirQuality(airQualityResult);
        }
    })
}

function renderAirQuality(airQuality) {
    stationNameEl.textContent = "Station Name: " + airQuality.name + " on " + airQuality.date.s;

    var aqi = document.createElement("tr");
    aqi.innerHTML = "<th>Air Quality Index</th><td>"+airQuality.aqi+"</td>"
    airQualityTableCellEl.appendChild(aqi);

    var humidity = document.createElement("tr");
    humidity.innerHTML = "<th>Humidity</th><td>"+airQuality.iaqi.h.v+"</td>"
    airQualityTableCellEl.appendChild(humidity);

    var oz = document.createElement("tr");
    oz.innerHTML = "<th>Ozone</th><td>"+airQuality.iaqi.o3.v+"</td>" //Error here
    airQualityTableCellEl.appendChild(oz);

    var pressure = document.createElement("tr");
    pressure.innerHTML = "<th>Atmospheric Pressure</th><td>"+airQuality.iaqi.p.v+"</td>"
    airQualityTableCellEl.appendChild(pressure);

    var pm25 = document.createElement("tr");
    pm25.innerHTML = "<th>PM2.5</th><td>"+airQuality.iaqi.pm25.v+"</td>"
    airQualityTableCellEl.appendChild(pm25);

    var co = document.createElement("tr");
    co.innerHTML = "<th>Carbon Monoxide</th><td>"+airQuality.iaqi.co.v+"</td>"
    airQualityTableCellEl.appendChild(co);
}
解决方案

错误核心是直接访问了可能不存在的嵌套属性(比如airQuality.iaqi.o3.v),当API返回的iaqi中没有对应指标字段时,层级属性会变成undefined,再访问.v就会抛出TypeError。以下是几种实用修复方式:

方式1:可选链操作符(?.)+ 默认值

使用ES6+的可选链操作符?.安全访问嵌套属性,配合??设置默认值(比如显示"N/A"表示无数据),修改renderAirQuality函数:

function renderAirQuality(airQuality) {
    stationNameEl.textContent = "Station Name: " + airQuality.name + " on " + airQuality.date.s;

    var aqi = document.createElement("tr");
    aqi.innerHTML = "<th>Air Quality Index</th><td>"+airQuality.aqi+"</td>"
    airQualityTableCellEl.appendChild(aqi);

    var humidity = document.createElement("tr");
    humidity.innerHTML = "<th>Humidity</th><td>"+(airQuality.iaqi.h?.v ?? "N/A")+"</td>"
    airQualityTableCellEl.appendChild(humidity);

    var oz = document.createElement("tr");
    oz.innerHTML = "<th>Ozone</th><td>"+(airQuality.iaqi.o3?.v ?? "N/A")+"</td>"
    airQualityTableCellEl.appendChild(oz);

    var pressure = document.createElement("tr");
    pressure.innerHTML = "<th>Atmospheric Pressure</th><td>"+(airQuality.iaqi.p?.v ?? "N/A")+"</td>"
    airQualityTableCellEl.appendChild(pressure);

    var pm25 = document.createElement("tr");
    pm25.innerHTML = "<th>PM2.5</th><td>"+(airQuality.iaqi.pm25?.v ?? "N/A")+"</td>"
    airQualityTableCellEl.appendChild(pm25);

    var co = document.createElement("tr");
    co.innerHTML = "<th>Carbon Monoxide</th><td>"+(airQuality.iaqi.co?.v ?? "N/A")+"</td>"
    airQualityTableCellEl.appendChild(co);
}

?.会在属性不存在时返回undefined,??则在左侧为undefined或null时使用默认值,既避免报错又保证页面显示友好。

方式2:提前判断属性是否存在

如果需要兼容不支持可选链的旧环境,可手动逐层判断属性是否存在:

function renderAirQuality(airQuality) {
    stationNameEl.textContent = "Station Name: " + airQuality.name + " on " + airQuality.date.s;

    var aqi = document.createElement("tr");
    aqi.innerHTML = "<th>Air Quality Index</th><td>"+airQuality.aqi+"</td>"
    airQualityTableCellEl.appendChild(aqi);

    // 湿度判断
    var humidityVal = airQuality.iaqi.h && airQuality.iaqi.h.v ? airQuality.iaqi.h.v : "N/A";
    var humidity = document.createElement("tr");
    humidity.innerHTML = "<th>Humidity</th><td>"+humidityVal+"</td>"
    airQualityTableCellEl.appendChild(humidity);

    // 臭氧判断
    var ozVal = airQuality.iaqi.o3 && airQuality.iaqi.o3.v ? airQuality.iaqi.o3.v : "N/A";
    var oz = document.createElement("tr");
    oz.innerHTML = "<th>Ozone</th><td>"+ozVal+"</td>"
    airQualityTableCellEl.appendChild(oz);

    // 气压判断
    var pressureVal = airQuality.iaqi.p && airQuality.iaqi.p.v ? airQuality.iaqi.p.v : "N/A";
    var pressure = document.createElement("tr");
    pressure.innerHTML = "<th>Atmospheric Pressure</th><td>"+pressureVal+"</td>"
    airQualityTableCellEl.appendChild(pressure);

    // PM2.5判断
    var pm25Val = airQuality.iaqi.pm25 && airQuality.iaqi.pm25.v ? airQuality.iaqi.pm25.v : "N/A";
    var pm25 = document.createElement("tr");
    pm25.innerHTML = "<th>PM2.5</th><td>"+pm25Val+"</td>"
    airQualityTableCellEl.appendChild(pm25);

    // 一氧化碳判断
    var coVal = airQuality.iaqi.co && airQuality.iaqi.co.v ? airQuality.iaqi.co.v : "N/A";
    var co = document.createElement("tr");
    co.innerHTML = "<th>Carbon Monoxide</th><td>"+coVal+"</td>"
    airQualityTableCellEl.appendChild(co);
}

通过&&运算符逐层验证属性存在性,只有当所有层级属性都有效时才取值,否则用默认值替代。

方式3:封装工具函数简化判断

如果指标较多,可封装工具函数统一处理安全取值逻辑,减少重复代码:

// 工具函数:安全获取嵌套属性,不存在则返回默认值
function getSafeValue(obj, path, defaultValue = "N/A") {
    return path.split('.').reduce((current, key) => {
        return current && current[key] ? current[key] : defaultValue;
    }, obj);
}

function renderAirQuality(airQuality) {
    stationNameEl.textContent = "Station Name: " + airQuality.name + " on " + airQuality.date.s;

    var aqi = document.createElement("tr");
    aqi.innerHTML = "<th>Air Quality Index</th><td>"+airQuality.aqi+"</td>"
    airQualityTableCellEl.appendChild(aqi);

    var humidity = document.createElement("tr");
    humidity.innerHTML = "<th>Humidity</th><td>"+getSafeValue(airQuality.iaqi, 'h.v')+"</td>"
    airQualityTableCellEl.appendChild(humidity);

    var oz = document.createElement("tr");
    oz.innerHTML = "<th>Ozone</th><td>"+getSafeValue(airQuality.iaqi, 'o3.v')+"</td>"
    airQualityTableCellEl.appendChild(oz);

    var pressure = document.createElement("tr");
    pressure.innerHTML = "<th>Atmospheric Pressure</th><td>"+getSafeValue(airQuality.iaqi, 'p.v')+"</td>"
    airQualityTableCellEl.appendChild(pressure);

    var pm25 = document.createElement("tr");
    pm25.innerHTML = "<th>PM2.5</th><td>"+getSafeValue(airQuality.iaqi, 'pm25.v')+"</td>"
    airQualityTableCellEl.appendChild(pm25);

    var co = document.createElement("tr");
    co.innerHTML = "<th>Carbon Monoxide</th><td>"+getSafeValue(airQuality.iaqi, 'co.v')+"</td>"
    airQualityTableCellEl.appendChild(co);
}

工具函数getSafeValue通过遍历属性路径逐层检查,最终返回对应值或默认值,让代码更简洁易维护。


内容的提问来源于stack exchange,提问作者Frances Cortuna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:40:18