I have an array of books which comes from an API.I want to filter the books array and put the selected book on a new array when the user selects a value from the dropdown.So,my book will have a dropdown which will have 3 values : 1)Currently Reading 2) Want to Read and 3) Read. Now I have created 3 arrays in my react state. So,when the user selects a value from the dropdown, it moves the book to the array defined for it.I have a handleChange() function for that purpose which will get the value of the array but I am not able to figure out how to remove the book selected from the books array and move it to the selected option array. So how do I filter out the books array based on the condition and put it to the new array.
Updated BooksList Code:
import React, { Component } from 'react';
class BooksList extends Component {
constructor(props) {
super(props);
this.state={
showSearchPage: false,
books: this.props.books.map(book => Object.assign({}, book, {status:"none"}))
};
this.handleChange = this.handleChange.bind(this);
}
handleChange=(index,event) => {
let books = this.state.books;
books[index].status = event.target.value;
this.setState({ books });
}
componentWillReceiveProps(nextProps) {
if (this.props.books !== nextProps.books) {
this.setState({ books: nextProps.books.map(book => Object.assign({}, book, { status: "none" })) });
}
}
render() {
return(
<div className="app">
{this.state.showSearchPage ? (
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" onClick={() => this.setState({ showSearchPage: false })}>Close</a>
<div className="search-books-input-wrapper">
{
<input type="text" placeholder="Search by title or author"/>
</div>
</div>
<div className="search-books-results">
<ol className="book-search">
{<div className="book-search">
{this.state.books.map( (book,index) =>
<div key={index} className="book">
<div className="book-top">
<div className="book-cover" style={{ width: 128, height: 193,margin:10, backgroundImage: `url(${book.imageLinks.smallThumbnail})` }}></div>
<div className="book-shelf-changer">
<select
value={book.status}
onChange={(event) => this.handleChange(book.index,event)}>
<option value="none" disabled> Move to...</option>
<option value="currentlyReading">✔ Currently Reading</option>
<option value="wantToRead"> Want to Read</option>
<option selected="selected" value="read"> Read</option>
<option value="none"> None</option>
</select>
</div>
</div>
<div className="book-title">{book.title}</div>
<div className="book-authors">{book.authors}</div>
<p>{book.status}</p>
</div>
)}
</div>
}
App.js:
import React from 'react'
// import * as BooksAPI from './BooksAPI'
import './App.css'
import * as BooksAPI from './BooksAPI'
import BooksList from './BooksList'
class BooksApp extends React.Component {
state = {
showSearchPage: false,
selectValue: 'None',
books: []
}
componentDidMount() {
BooksAPI.getAll().then((books) => {
this.setState({ books })
console.log(books[0])
})
}
render() {
return (
<BooksList books={this.state.books}/>
)
}
}
export default BooksApp
So how do I write my handleChange method to get the selected array?
Edit 1: Updated the code.
So, below is the error I get in the console:
Uncaught TypeError: Cannot set property 'status' of undefined
at BooksList._this.handleChange (BooksList.js:17)
at Object.executeOnChange (LinkedValueUtils.js:130)
at ReactDOMComponent._handleChange (ReactDOMSelect.js:188)
at HTMLUnknownElement.boundFunc (ReactErrorUtils.js:63)
at Object.ReactErrorUtils.invokeGuardedCallback (ReactErrorUtils.js:69)
at executeDispatch (EventPluginUtils.js:83)
at Object.executeDispatchesInOrder (EventPluginUtils.js:106)
at executeDispatchesAndRelease (EventPluginHub.js:41)
at executeDispatchesAndReleaseTopLevel (EventPluginHub.js:52)
at Array.forEach (<anonymous>)
Edit 2: Added the App.js file that contains the ComponentDidMount lifecycle method: