简体   繁体   English

未捕获的类型错误:无法使用 Google 图书 API 读取未定义的属性“1”

[英]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.

相关问题 未捕获到的TypeError:无法读取Google Map API中未定义的属性“ PlacesService” - Uncaught TypeError: Cannot read property 'PlacesService' of undefined in google map api 未捕获的TypeError:无法读取undefined的属性&#39;row&#39; - google visualization api - Uncaught TypeError: Cannot read property 'row' of undefined - google visualisation api Uncaught TypeError:无法读取未定义的属性“ calendar”-Google Calendar API - Uncaught TypeError: Cannot read property 'calendar' of undefined - Google Calendar API 未捕获的TypeError:无法读取未定义的属性“ 0”(Google Feed API) - Uncaught TypeError: Cannot read property '0' of undefined (Google Feed API) 未捕获的TypeError:无法读取未定义的属性“ URL”-Google Image API - Uncaught TypeError: Cannot read property 'url' of undefined - Google Image API Google Books API:无法读取未定义的属性“缩略图” - Google Books API: Cannot read property 'thumbnail' of undefined Google Books API“无法读取未定义的属性“ 0” - “Cannot read property ”0“ from undefined” for Google Books API 谷歌地图“未捕获的类型错误:无法读取未定义的属性‘defaultView’” - Google Maps "Uncaught TypeError: Cannot read property 'defaultView' of undefined" 未捕获的TypeError:无法读取未定义的Google Map和jquery的属性&#39;x&#39; - Uncaught TypeError: Cannot read property 'x' of undefined Google Map and jquery Uncaught TypeError:无法读取未定义的Google Maps的属性“ apply” - Uncaught TypeError: Cannot read property 'apply' of undefined Google Maps
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM