Retrieving Book Title using Google Books API and ISBN

As a newcomer to Javascript and React-Native, I am in the process of developing a simple app that scans book barcodes for their ISBN numbers and matches them with their titles. Despite successfully retrieving the ISBN number, I am encountering an issue when trying to fetch the book title from the Google Books API. The error message "undefined is not an object (evaluating '_this.state.results.items[0].title)" keeps appearing. Can someone assist me in identifying the problem and suggest steps to resolve it? Thank you! Please excuse any errors or shortcomings in my code, as I am still learning and appreciate your guidance.

import React from 'react';
import { Dimensions, StyleSheet, Text, View } from 'react-native';
import { BarCodeScanner } from 'expo';

const { width } = Dimensions.get('window');

export default class App extends React.Component {

  constructor(props) {
    super(props);

    this.state= {
      results: {
        kind: '',
        totalItems: 0,
        items: []
      }
    }
    this.fetchData = this.fetchData.bind(this);
  }


  fetchData(isbn) {
    fetch(`https://www.googleapis.com/books/v1/volumes?q=isbn:${encodeURIComponent(isbn)}`)
    .then((response)=> response.json())
    .then((responseData)=> {
      this.setState({results: responseData})
    });

  }

  _handleBarCodeRead = ({ type, data }) => {
    var isbn = data;
    this.fetchData(isbn)
    var title = this.state.results.items[0].volumeInfo.title;
    alert(`ISBN: ${isbn}, Title: ${title}`)
  }

  render() {
    return (
      <BarCodeScanner
        onBarCodeRead={this._handleBarCodeRead}
        style={[StyleSheet.absoluteFill, styles.container]}
      >
        <View style={styles.layerTop} />
        <View style={styles.layerCenter}>
          <View style={styles.layerLeft} />
          <View style={styles.focused} />
          <View style={styles.layerRight} />
        </View>
        <View style={styles.layerBottom} />
      </BarCodeScanner>
    );
  }
}

Edit: After realizing my URL was missing "isbn:", I managed to rectify it and now the alert displays the correct book title matched with the ISBN. However, despite receiving the alert, I continue to encounter the same "undefined is not an object (evaluating '_this.state.results.items[0].title)" message.

Answer №1

It seems like you're attempting to access the title attribute in the incorrect place.

Consider updating it to

let title = this.state.results.items[0].volumeInfo.title;

https://i.sstatic.net/qAvJd.png

Answer №2

A race condition is causing the alert to occur before the setState is completed. One solution is to utilize a callback() function.

  fetchData(isbn, callback) {
    fetch(`https://www.googleapis.com/books/v1/volumes?q=isbn:${encodeURIComponent(isbn)}`)
        .then(response => response.json())
        .then(responseJson => {
            this.setState({ bookInfo: responseJson.items[0].volumeInfo.title});
            callback();
        })
    .catch(error => {
      console.error(error);
    });
  }

  alertInfo = () => {
      var title = this.state.bookInfo;
      alert(`Title: ${title} was scanned!`);
  }


  handleBarCodeScanned = ({ data }) => {
    var isbn = data;
    this.setState({ scanned: true });
    this.fetchData(isbn, this.alertInfo);
  };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

display dynamic graphs using json data from a php backend

I'm having trouble displaying a graph using JSON data in Highcharts. Here is a sample of what I need: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/column-rotated-labels/ The file values ...

Manipulate objects in three.js to always face the mouse pointer

It seems that despite my efforts, I am struggling with this task as I am relatively new to it. Surprisingly, I am not getting any errors in Dreamweaver. I've started fresh by integrating the look at function with the OBJ loader, camera, and lights in ...

Having trouble accessing data beyond the login page using Node/Express

Currently in an unusual situation. I am developing a backend and frontend that connects to a third-party RESTFUL API managing some hardware. The third-party API is hosted on your local system as a webserver, meaning HTTP requests are directed to "localhost ...

Leverage Vue's ability to assign data from a parent component to

I am struggling to bind the data (inputData) from the parent component to my child component. I have checked my code multiple times but cannot find where the mistake is. MainApp.js let vm = new Vue({ el: "#app", components: { &ap ...

"Angular File Upload Made Easy with Drag-and-Drop Functionality and Cleverly Positioned

Encountering an issue with Angular File upload in conjunction with relatively positioned elements. The drop target is set to 100% width and height, absolutely positioned. While dragging a file over any non-relatively positioned element, the overlay functio ...

Guide on including the angular value (id) in conjunction with repeating data-target for executing a function

I have the following code snippet. Now, I am trying to pass a dynamic AngularJS variable, specifically the id of a repeating list. The button in question is used for deactivation purposes, and upon clicking it, a confirmation box pops up. Upon confirming ...

Uh oh! There seems to be an issue with the ClerkJS frontendAPI option. Visit the homepage at https://dashboard.clerk.dev to retrieve your unique Frontend API value

Despite inputting the correct Clerk API keys, I'm encountering issues with the functionality of the ClerkJS API. I anticipate that the application should enable me to utilize the ClerkJS API for user authentication without any problems. ...

Determine the total value of a specific key within a collection of objects

I am grappling with an array of objects: let fileArray = [ { filename: 'File1.txt', bytes: 12345, created: 1548360783511.728 }, { filename: 'File2.txt', bytes: 34567, created: 1548361491237.182 }, { filename: 'File3.txt&apos ...

Waiting for a webpage to fully load with JavaScript in Selenium

I am facing an issue where I need to wait for the page to fully load before executing a certain action. It is important for me that the loading circle on the browser tab stops spinning before proceeding. The current Ajax function I am using does not work c ...

The backend error message isn't triggering an alert!

My current issue involves using jQuery to execute a .php file. Whenever an error occurs in the backend, I want to display an alert message with the error details. However, when intentionally submitting with an error, no alert pops up and it just proceeds t ...

What is the best way to extract individual words from a string based on a specified list of tokens?

I am currently working with a list of tokens used to create artificial Japanese words, which is represented by the following array: var syllables = ["chi","tsu","shi","ka","ki","ku","ke","ko","ta","te","to","sa","su","se","so","na","ni","nu","ne","no","ha ...

Executing two Ajax calls in ReactJS with different parameters can improve the efficiency of your

Why does the second Ajax call overwrite the first one, causing the results to be different each time I refresh it? In the first Ajax call, I have set tests: [], testsHistories: [] in the setState function. However, the second Ajax call only sets the stat ...

Show the GitHub repositories of the user within a React application

Even though I am relatively new to React, I managed to create a GitHub search application. In this app, you can input a user's name in a search box and view their avatar, bio, username, etc. However, I'm facing an issue with fetching their reposi ...

best way to extract information from JSON data and display it within an iOS application

How can I store the objects coming in an array into an object so that when I use something like myArray.id= myArray.name= it will show values? SBJsonParser *parser = [[SBJsonParser alloc] init]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSU ...

"Enhance Your Vue Files with the Image Overlay Extension for FilePond

I'm trying to add a review button to an image, but I can't seem to find the right attribute for it. I've set the imagePreviewMarkupShow = true but it doesn't seem to be working. Check out the package here This is My Template < ...

Using a function as an argument to handle the onClick event

I have a function that generates a React.ReactElement object. I need to provide this function with another function that will be triggered by an onClick event on a button. This is how I call the main function: this._createInjurySection1Drawer([{innerDra ...

combine and refresh identical items within an array

Currently, I am in the process of creating a prototype for an item-list and a shopping-cart. Both components function as standalone entities but are connected through a vuex-store. The item-list contains various elements that can be added to the shopping-c ...

No server needed reCAPTCHA

I have successfully integrated reCAPTCHA into a Contact form on my website, which includes three fields: name, email, and message. The data from this form is stored in Firebase for easy access. This implementation was done using React, with the help of th ...

Leveraging entities within entities with connections and seeding data in Nest JS / TypeORM

Imagine we are developing our initial entities for a brand new web application. We start with an entity for users: @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() username: string; @Column() password: string; ...

Tips for restricting function invocations in JavaScript?

I am seeking a function called limitCalls(fn, maxCalls) which accepts a function fn and creates a new function that can only be called the specified number of times in maxCalls. Here is a test example: it('limitCalls', () => { const makeIncre ...