未捕获的类型错误:无法读取未定义但已定义的属性
2022-01-21
510
此应用程序的目的是对 Google Places API 进行 API 调用,收集有关餐厅的信息,然后显示给用户。
该应用程序在大多数情况下都可以正常工作,但平均每 5-10 次 API 调用一次,应用程序就会崩溃。
错误:
代码:
// State and global variables //
const [searchResponse, setSearchResponse] = useState("");
const [secondarySearchResponse, setsecondarySearchResponse] = useState("");
const [information, setInformation] = useState("");
const [secondaryInformation, setSecondaryInformation] = useState("");
const [itemFilter, setFilter] = useState("");
const [place_id, setPlaceId] = useState("");
const [dataReady, setDataReady] = useState(false);
const [locationHad, setLocationHad] = useState(false);
const pos = useRef(null);
const key = "AIzaSyD1ZTsmbDBBlMpmaogO_hlj93zzbDDtAoc";
var num = Math.floor(Math.random() * 20 + 1);
// Use Effects
// Gets users current location
useEffect(() => {
navigator.geolocation.getCurrentPosition((position) => {
pos.current = position;
console.log("Location had. Ready for API call.");
setLocationHad(true);
});
}, []);
// Once we have clicked our button and made our api call, we get the place_id and save it so we can make a secondary api call using place_id
useEffect(() => {
if (
searchResponse !== "" &&
searchResponse.results[num].place_id !== undefined) {
setPlaceId(searchResponse.results[num].place_id);
console.log("place_id set");
} else {
console.log("error in setting place_id");
}
}, [searchResponse]);
// One place_id is set we make secondary api call
useEffect(() => {
if (place_id !== "") {
fetchSecondaryInfo();
} else {
console.log("no place id!");
}
}, [place_id]);
// Now that we have made both api calls we save the relavent info into state that we will pass down to child components
useEffect(() => {
if (searchResponse !== "") {
console.log(searchResponse.results[num].name);
setInformation({
name: searchResponse.results[num].name,
open_now: searchResponse.results[num].opening_hours.open_now,
rating: searchResponse.results[num].rating,
price: searchResponse.results[num].price_level,
location: {
lat: searchResponse.results[num].geometry.location.lat,
lng: searchResponse.results[num].geometry.location.lng,
},
});
console.log("info set!");
} else {
console.log("no info to set!");
}
}, [searchResponse]);
// And again for the secondary info (I broke this dwown into to seperate useEffects trying to figure out what was causing my error...)
useEffect(() => {
if (secondarySearchResponse !== "") {
setSecondaryInformation({
phone_number: secondarySearchResponse.result.formatted_phone_number,
daily_hours: secondarySearchResponse.result.opening_hours.weekday_text,
address: secondarySearchResponse.result.formatted_address,
});
setDataReady(true);
console.log("secondary info set!");
} else {
console.log("no secondary info to set!");
}
}, [secondarySearchResponse]);
// Function that makes api call
async function fetchInfo() {
if (locationHad) {
if (itemFilter === "") {
var url = `https://secure-dawn-88985.herokuapp.com/https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${pos.current.coords.latitude},${pos.current.coords.longitude}&radius=12000&type=restaurant&key=${key}`;
} else {
var url = `https://secure-dawn-88985.herokuapp.com/https://maps.googleapis.com/maps/api/place/nearbysearch/json?keyword=${itemFilter[0]}&location=${pos.current.coords.latitude},${pos.current.coords.longitude}&radius=12000&type=restaurant&key=${key}`;
}
await fetch(url)
.then((response) => response.json())
.then((data) => setSearchResponse(data))
.then(console.log("api request fired."));
} else {
console.log("location not yet identified!");
}
}
// Function that makes secondary api call
async function fetchSecondaryInfo() {
if (place_id !== "") {
const secondary_url = `https://secure-dawn-88985.herokuapp.com/https://maps.googleapis.com/maps/api/place/details/json?fields=formatted_phone_number,opening_hours,formatted_address&place_id=${place_id}&key=${key}`;
await fetch(secondary_url)
.then((response) => response.json())
.then((data) => setsecondarySearchResponse(data))
.then(console.log("secondary api request fired."));
} else {
console.log("place_id not had in secondary fetch.");
}
}
至于 place_id 错误,我输入了一行特定的代码来避免此错误:
useEffect(() => {
if (
searchResponse !== "" &&
searchResponse.results[num].place_id !== undefined
) {
console.log(searchResponse.results[num].place_id);
setPlaceId(searchResponse.results[num].place_id);
console.log("place_id set");
} else {
console.log("error in setting place_id");
}
}, [searchResponse]);
所以我不明白在那一行中怎么可能抛出这个错误。
至于名称错误,我输入了一行特定的代码来控制台记录对象在读取属性之前会失败,但在抛出错误之前不会在控制台中打印:
useEffect(() => {
if (searchResponse !== "") {
console.log(searchResponse.results[num].name);
setInformation({
name: searchResponse.results[num].name,
open_now: searchResponse.results[num].opening_hours.open_now,
rating: searchResponse.results[num].rating,
price: searchResponse.results[num].price_level,
location: {
lat: searchResponse.results[num].geometry.location.lat,
lng: searchResponse.results[num].geometry.location.lng,
},
});
console.log("info set!");
..........
我很感激任何意见、建议、批评等。
1个回答
错误消息显示错误在 此 行抛出:
searchResponse.results[num].place_id !== undefined
如果
searchResponse.results[num]
不存在,则会抛出此错误。
为了简洁起见,请尝试使用可选链接(并将
searchResponse
初始化为未定义或 null)。执行
const [searchResponse, setSearchResponse] = useState();
并将
if (
searchResponse !== "" &&
searchResponse.results[num].place_id !== undefined) {
setPlaceId(searchResponse.results[num].place_id);
更改为
const possiblePlaceId = searchResponse?.results[num]?.place_id;
if (possiblePlaceId) {
setPlaceId(possiblePlaceId);
CertainPerformance
2022-01-21