Reputation: 55
I'm trying to get a feel for reactjs, new to front end development. Google Books API is simple so I decided to use it to build a react page that lists 10 books given the user input.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
const GOOGLE_BOOKS_API = 'https://www.googleapis.com/books/v1/volumes?q=';
const GOOGLE_BOOKS_API_LIMIT = 'maxResults=10';
class BookItem extends React.Component {
render() {
return (
<div>
<img alt="Book" src={this.props.data.volumeInfo.imageLinks.thumbnail} />
<span>{this.props.data.volumeInfo.imageLinks.thumbnail}</span>
</div>
);
}
}
class BookResults extends React.Component {
render() {
const isBookResultsEmpty = !(this.props.books && this.props.books.length > 1);
const bookItems = isBookResultsEmpty ? [] : this.props.books.map((book,index) =>
<BookItem key={index} data={book} />
);
return (
<div className='book-results'>
{isBookResultsEmpty ? (
<h1>No Results</h1>
) : (
<div> {bookItems} </div>
)}
</div>
);
}
}
class BookSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
bookQuery: '',
books: []
};
this.handleInputChange = this.handleInputChange.bind(this);
this.getBooks = this.getBooks.bind(this)
}
getBooks() {
let queryString = '';
if (this.state.bookQuery && this.state.bookQuery.length > 1) {
queryString = this.state.bookQuery.replace(/\s/g, '+');
fetch(`${GOOGLE_BOOKS_API}${queryString}&${GOOGLE_BOOKS_API_LIMIT}`)
.then(results => {
return results.json();
})
.then(json => {
this.setState({
books: json.items
});
})
.catch(e => console.log('error', e));
}
}
handleInputChange(event) {
this.setState({
bookQuery: this.search.value
},
this.getBooks());
}
render() {
return (
<div className="book-search">
<form>
<input
placeholder="Search for Books"
ref={input => this.search = input}
onChange={this.handleInputChange}
/>
</form>
<BookResults books={this.state.books} />
</div>
);
}
}
ReactDOM.render(<BookSearch />, document.getElementById('root'));
I get an error when typing the input:
TypeError: Cannot read property 'thumbnail' of undefined
I added a check for the data in the BookResults component but the error still occurs. I assume it has to do with the state or props value changing while rendering, but I don't know enough about React to be sure
Upvotes: 1
Views: 276
Reputation: 112897
Some books don't have imageLinks
, so you need to make sure it is not undefined
before you use it.
Example
class BookItem extends React.Component {
render() {
const { imageLinks } = this.props.data.volumeInfo;
if (!imageLinks) {
return null;
}
return (
<div>
<img alt="Book" src={imageLinks.thumbnail} />
<span>{imageLinks.thumbnail}</span>
</div>
);
}
}
Upvotes: 3