Search code examples
javascriptfetch-api

My fetch request to openlibrary is getting caught


I'm trying to write a fetch request to the openlibrary API but so far it keeps getting caught and returning a console.log error. I'm thinking I'm entering the URL incorrectly but I'm not sure. I've tried rephrasing it a couple of ways but so far hasn't worked. I'm relatively new to writing fetch.

It's making a search of ISBN. It's . I also wanted to verify I have the data property for ebook availability in the correct format when I refer to it to create the text.


var fetchRequest = function() {

          var isbn = '0553283685';
          //var searchURL = `https://openlibrary.org/api/books?bibkeys=ISBN:" + ISBN${isbn}&format=json&jscmd=data`; 

          var searchURL = "https://openlibrary.org/api/books?bibkeys=ISBN:" + isbn + "&format=json&jscmd=data";
          
          fetch(searchURL)
          .then(function(response) {
              return response.json();
          })
          .then(function(response2) {
              return response2.items.map(function(book) {
                createBookList(book)
              })   

            })  
          .catch( function()  {
              console.log(`There was an error with the fetch request`);       
          }); 
      }       

My createBookList function:

   var createBookList = function(book) {   

      var li = document.createElement('li');        
      var div = document.createElement('div');
      var singleBookRow = document.createElement('div');        
  
      var bookEPUB = document.createElement('p');
      var bookPDF = document.createElement('p');
      var bookTEXT = document.createElement('p');
      var bookREAD = document.createElement('p');

              bookEPUB.textContent = book.ebooks.availability.epub_url;
              bookPDF.textContent = book.ebooks.availability.pdf_url;
              bookTEXT.textContent = book.ebooks.availability.text_url;
              bookREAD.textContent = book.ebooks.availability.read_url;


        div.appendChild(bookEPUB);
        div.appendChild(bookPDF);
        div.appendChild(bookTEXT);
        singleBookRow.appendChild(bookREAD);
        singleBookRow.appendChild(div);
        li.appendChild(singleBookRow);
        booksList.appendChild(li);
  
        li.classList.add('list-group-item');
        singleBookRow.classList.add('row');
        div.classList.add('columns-large-4');

     
        /// 'Check availability' button 

        var checkAvailability = document.createElement('input');   
        checkAvailability.type='button';   
        checkAvailability.onclick=(book);    
        div.append(checkAvailability);     
        
    } 

Solution

  • first, print the error:

    // omit stuff...
              .catch( function(e)  {
                  console.log(e)
                  console.log(`There was an error with the fetch request`);       
              }); 
    // omit stuff...
    

    from error TypeError: Cannot read properties of undefined (reading 'map'), we can know that the response type is unexpected. let's check it:

    // omit stuff...
              .then(function(response2) {
                  console.log(JSON.stringify(response2))
                  return response2.items.map(function(book) {
    // omit stuff...
    

    what's this? a dictionary.

    {"ISBN:0553283685":{"url":"https://openlibrary.org/books/OL16710277M/Hypérion","key":"/books/OL16710277M","title":"Hypérion"}, ...}'
    

    so, it turns out that you can't parse the result this way. To iterate over dictionary, use this:

    (function() {
    
              var isbn = '0553283685';
              //var searchURL = `https://openlibrary.org/api/books?bibkeys=ISBN:" + ISBN${isbn}&format=json&jscmd=data`; 
    
              var searchURL = "https://openlibrary.org/api/books?bibkeys=ISBN:" + isbn + "&format=json&jscmd=data";
              
              fetch(searchURL)
              .then(function(response) {
                  return response.json();
              })
              .then(function(response2) {
                  books = []
                  for (const [key, value] of Object.entries(response2)) {
                      books.append(createBookList(book))
                  }
                  return books
    
                })