[英]Uncaught TypeError: Cannot read property '1' of undefined using Google Books API
I'm working on a book finder app, using the Google Books API that pulls the search results.我正在开发一个图书查找器应用程序,使用 Google Books API 来提取搜索结果。 On the first search, I am seeing the below error in the console.
在第一次搜索时,我在控制台中看到以下错误。 Every subsequent search after the first, pulls the search terms as it should.
第一次之后的每个后续搜索都会按应有的方式提取搜索词。
Have I got an undefined property somewhere?我在某处有未定义的属性吗? Or is there an array that is not iterating correctly?
或者是否存在未正确迭代的数组?
Error:错误:
main.js:65 Uncaught TypeError: Cannot read property '1' of undefined
at displayResults (main.js:65)
at Object.success (main.js:35)
at i (jquery.min.js:2)
at Object.fireWith [as resolveWith] (jquery.min.js:2)
at A (jquery.min.js:4)
at XMLHttpRequest.<anonymous> (jquery.min.js:4)
JS file: JS文件:
$(document).ready(function() {
var item, title, author, publisher, bookLink, bookImg;
var outputList = document.getElementById("list-output");
var bookUrl = "https://www.googleapis.com/books/v1/volumes?q=";
var apiKey = "key=AIzaSyDtXC7kb6a7xKJdm_Le6_BYoY5biz6s8Lw";
var placeHldr = '<img src="https://via.placeholder.com/150">';
var searchData;
//listener for search button
$("#search").submit(function() {
outputList.innerHTML = ""; //empty html output
document.body.style.backgroundImage = "url('')";
searchData = $("#search-box").val();
console.log(searchData);
//handling empty search input field
if(searchData === "" || searchData === null) {
displayError();
}
else {
// console.log(searchData);
// $.get("https://www.googleapis.com/books/v1/volumes?q="+searchData, getBookData()});
$.ajax({
url: bookUrl + searchData,
dataType: "json",
success: function(response) {
console.log(response);
if (response.totalItems === 0) {
alert("no result!.. try again");
}
else {
$("#title").animate({'margin-top': '5px'}, 1000); //search box animation
$(".book-list").css("visibility", "visible");
displayResults(response);
}
},
error: function () {
alert("Something went wrong.."+"Try again!");
}
});
}
$("#search-box").val(""); //clear search box
});
/*
* function to display result in index.html
* @param response
*/
function displayResults(response) {
for (var i = 0; i < response.items.length; i+=2) {
item = response.items[i];
title1 = item.volumeInfo.title;
author1 = item.volumeInfo.authors;
publisher1 = item.volumeInfo.publisher;
bookLink1 = item.volumeInfo.previewLink;
bookIsbn = item.volumeInfo.industryIdentifiers[1].identifier;
bookImg1 = (item.volumeInfo.imageLinks) ? item.volumeInfo.imageLinks.thumbnail : placeHldr ;
item2 = response.items[i+1];
title2 = item2.volumeInfo.title;
author2 = item2.volumeInfo.authors;
publisher2 = item2.volumeInfo.publisher;
bookLink2 = item2.volumeInfo.previewLink;
bookIsbn2 = item2.volumeInfo.industryIdentifiers[1].identifier;
bookImg2 = (item2.volumeInfo.imageLinks) ? item2.volumeInfo.imageLinks.thumbnail : placeHldr ;
// in production code, item.text should have the HTML entities escaped.
outputList.innerHTML += '<div class="row mt-4">' +
formatOutput(bookImg1, title1, author1, publisher1, bookLink1, bookIsbn) +
formatOutput(bookImg2, title2, author2, publisher2, bookLink2, bookIsbn2) +
'</div>';
console.log(outputList);
}
}
/*
* card element formatter using es6 backticks and templates (indivial card)
* @param bookImg title author publisher bookLink
* @return htmlCard
*/
function formatOutput(bookImg, title, author, publisher, bookLink, bookIsbn) {
var viewUrl = 'book.html?isbn='+bookIsbn; //constructing link for bookviewer
var htmlCard = `<div class="col-lg-6">
<div class="card" style="">
<div class="row no-gutters">
<div class="col-md-4">
<img src="${bookImg}" class="card-img" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">${title}</h5>
<p class="card-text">Author: ${author}</p>
<p class="card-text">Publisher: ${publisher}</p>
<a target="_blank" href="${viewUrl}" class="btn btn-secondary">Read Book</a>
</div>
</div>
</div>
</div>
</div>`;
return htmlCard;
}
//handling error for empty search box
function displayError() {
alert("Search term can't be empty!");
}
});
It seems that you assume that all the object properties you access in displayResults(response)
exist.您似乎假设您在
displayResults(response)
中访问的所有 object 属性都存在。 In my experience when dealing with 3rd party APIs you can never be sure.根据我处理 3rd 方 API 的经验,你永远无法确定。 It would be better to check each property before accessing it to avoid errors.
最好在访问之前检查每个属性以避免错误。
This SO answer has some good starting points: How to check if object property exists with a variable holding the property name?这个 SO 答案有一些很好的起点: 如何检查 object 属性是否存在且变量包含属性名称?
Copied from that answer:从那个答案复制:
var myProp = 'prop';
if(myObj.hasOwnProperty(myProp)){
alert("yes, i have that property");
}
Or或者
var myProp = 'prop';
if(myProp in myObj){
alert("yes, i have that property");
}
Or或者
if('prop' in myObj){
alert("yes, i have that property");
}
Note that hasOwnProperty
doesn't check for inherited properties, whereas in
does.请注意,
hasOwnProperty
不会检查继承的属性,而in
会。 For example 'constructor' in myObj
is true, but myObj.hasOwnProperty('constructor')
is not.例如
'constructor' in myObj
为真,但myObj.hasOwnProperty('constructor')
不是。
Here is another useful article on that topic: https://dmitripavlutin.com/7-tips-to-handle-undefined-in-javascript/#22-accessing-non-existing-property .这是关于该主题的另一篇有用的文章: https://dmitripavlutin.com/7-tips-to-handle-undefined-in-javascript/#22-accessing-non-existing-property 。
From there:从那里:
Fortunately, JavaScript offers a bunch of ways to determine if the object has a specific property:幸运的是,JavaScript 提供了多种方法来确定 object 是否具有特定属性:
obj.prop !== undefined: compare against undefined directly
typeof obj.prop !== 'undefined': verify the property value type
obj.hasOwnProperty('prop'): verify whether the object has an own property
'prop' in obj: verify whether the object has an own or inherited property
My recommendation is to use in operator.我的建议是在运算符中使用。 It has a short and sweet syntax.
它有一个简短而甜美的语法。 in operator presence suggests a clear intent of checking whether an object has a specific property, without accessing the actual property value.
操作员在场表明检查 object 是否具有特定属性的明确意图,而不访问实际属性值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.