Promise成功渲染HTML时触发Cannot read properties of null错误排查
问题:链式Promise渲染HTML时出现"Cannot read properties of null (reading 'insertAdjacentHTML')"错误
我尝试链式调用两个Promise,第二个Promise执行成功后将结果渲染到HTML元素中。两个Promise可正常运行,但每次都会触发错误:Cannot read properties of null (reading 'insertAdjacentHTML'),期望renderCountry函数能正常渲染国家信息,但一直失败。
错误根源
这个错误的核心是countrycontainer变量为null,即document.querySelector('.countries')未找到对应的DOM元素。可能的触发原因:
- JavaScript代码在DOM完全加载前就执行了,此时浏览器还未解析出
.countries元素 - HTML页面中不存在class为
countries的容器元素
此外代码还有两个影响功能的小问题:
- 第一个
fetch的URL中,纬度参数多了个多余的9(latitude=${lat}9),会导致地理编码请求失效 - 第二个Promise的错误处理中,错误地引用了第一个请求返回数据的
data.status,实际应该使用当前response的status属性
修复方案
1. 确保DOM加载完成后执行JS代码
将所有JS代码包裹在DOMContentLoaded事件监听中,或者将script标签放在HTML的</body>标签前,保证执行代码时DOM已完全解析。
2. 确认HTML中存在目标容器
检查HTML代码,确保存在如下结构的容器:
<div class="countries"></div>
3. 修正地理编码请求URL
把latitude=${lat}9修改为latitude=${lat},修复参数错误。
4. 修正错误处理中的status引用
第二个fetch的错误提示里,将${data.status}改为${response.status},获取正确的响应状态码。
5. 增加容器存在性判断(可选但更健壮)
在renderCountry函数中先判断countrycontainer是否存在,避免意外报错。
修复后的完整代码
'use strict'; // 等待DOM加载完成后执行逻辑 document.addEventListener('DOMContentLoaded', function() { const countrycontainer = document.querySelector('.countries'); let country; /* 渲染国家信息到HTML */ const renderCountry = function (data, className = '') { const html = ` <div class="country ${className}"> <img class="country__img" src="${data.flag}" /> <div class="country__data"> <h3 class="country__name">${data.name}</h3> <h4 class="country__region">${data.region}</h4> <p class="country__row"><span>👫</span>${( +data.population / 1000000 ).toFixed(1)} people</p> <p class="country__row"><span>🗣️</span>${data.languages[0].name}</p> <p class="country__row"><span> Native Name 🗣️ </span>${ data.languages[0].nativeName }</p> <p class="country__row"><span>💰</span>${data.currencies[0].name}</p> </div> </div>`; // 先检查容器是否存在再操作 if (countrycontainer) { countrycontainer.insertAdjacentHTML('beforeend', html); countrycontainer.style.opacity = 1; } }; const whereAmI = function (lat, lng) { // 第一个请求:反向地理编码 fetch( `https://api.bigdatacloud.net/data/reverse-geocode-client?latitude=${lat}&longitude=${lng}&localityLanguage=en` ) .then(response => { console.log(response); if (!response.ok) throw new Error(`${response.status} 坐标无效`); return response.json(); }) .then(data => { console.log(data); console.log(`你在 ${data.city}, ${data.countryName}`); // 第二个请求:获取国家信息 return fetch(`https://restcountries.com/v2/name/${data.countryName}`) .then(response => { if (!response.ok) throw new Error( `${response.status} 未找到该国家,请重试` ); return response.json(); }) .then(data => { console.log('国家数据:'); console.log(data); renderCountry(data[0]); }); }) .catch(error => { console.log(`${error},请重试`); }); }; whereAmI(4.57, -74.2973); whereAmI(37.98381, 23.727539); });
内容的提问来源于stack exchange,提问作者Christos
相关产品推荐
相关产品推荐

