0

I have to components. First is EditBook Component, which fetches books details and then passes it to the UpdateBook component. However, none of my keystrokes are being binded to the inputbox. Can anyone please help in debugging this. Here is EditBook -

"use strict";

import React from "react";
import ListingHeader from "./listingHeader";
import Listings from "./listings";
import UpdateBook from "./updateBook";
import { Route,Switch } from 'react-router-dom';

const BOOK_DETAILS_API_ENDPOINT = 'http://localhost:5001/api/v1/books/';
const header = new Headers({
    'Access-Control-Allow-Origin':'*',
    'Content-Type': 'multipart/form-data'
});

class EditBook extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            book: {},
            isLoading: false,
            error: null,
        };
    }

    componentDidMount() {
        this.setState({ isLoading: true });

        fetch(BOOK_DETAILS_API_ENDPOINT+this.props.match.params.id,{headers:header})
        .then(response => {
            if (response.ok) {
              return response.json();
            } else {
              throw new Error('Something went wrong ...');
            }
        })
        .then(data => {
            this.setState({ book: data.data,isLoading: false })
        })
        .catch(error => this.setState({ error, isLoading: false }));
    }



    render() {
        const { book,isLoading,error } = this.state;
        return (
            <section className="bg-light" id="portfolio">
                <div className="container">
                    <br/><br/>
                    <UpdateBook book={book} />
                </div>    
          </section>
        );
    }

};

export default EditBook;

And UpdateBook is like this -

"use strict";

import React from "react";
import ListingHeader from "./listingHeader";
import Notifications, {notify} from 'react-notify-toast';
import InputBox from '../ui/inputBox';

const UPDATE_BOOK_API_ENDPOINT  =   'http://localhost:5001/api/v1/books/';
const headers = new Headers({
    'Access-Control-Allow-Origin':'*',
    'Content-Type': 'application/x-www-form-urlencoded'
});

class UpdateBook extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            book:{}
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentWillReceiveProps(newProps) {
        if (newProps.book !== this.props.book) {
            this.setState({book: newProps.book});
        }    
    }

    handleChange(e) {
       console.log(this.state.book[e.target.name]); 
       this.state.book[e.target.name] = e.target.value

       console.log(this.state.book[e.target.name]); 
    }

    handleSubmit(event) {        
        event.preventDefault();

        fetch(UPDATE_BOOK_API_ENDPOINT+this.state.book.id, {
            method: 'put',
            headers: headers,
            body:    'isbn_13='+this.state.book.isbn_13+'&isbn_10='+this.state.book.isbn_10+'&title='+this.state.book.title+'&publisher='+this.state.book.publisher+'&author='+this.state.book.author+'&page_count='+this.state.book.page_count+'&date_of_purchase='+this.state.book.date_of_purchase+'&classification='+this.state.book.classification+'&genre='+this.state.book.genre+'&first_published='+this.state.book.first_published+'&description='+this.state.book.description
        })
        .then(response => {
            if (response.ok) {
              return response.json();
            } else {
              throw new Error('Something went wrong ...');
            }
        })
        .then(data => {
            this.setState({ book: data.data,bookAdded: true });
            notify.show('book updated successfully!','success');
        })
        .catch(error => {
            notify.show('Something is wrong with something!','error');
            this.setState({ error, isLoading: false })
        });
    }

    render() {

        return (

            <section className="bg-light" id="portfolio">
                <div className="container">
                    <div className="row " >
                        <div className="col-xs-18 col-sm-12 col-md-12 card text-left">
                            <br/>
                            <h4 className="text-center">Edit {this.state.book.title}</h4>
                            <form onSubmit={this.handleSubmit} type="post" >
                                <Notifications />

                                <div className="centerDiv">
                                    <img src={this.state.book.thumbnail_url} className="form-control text-center"/>
                                    <input type="file" className="form-control-file" id="exampleInputFile" aria-describedby="fileHelp" name="thumbnail_url" />
                                </div>

                                <div className="form-group">
                                    <label htmlFor="isbn_10">ISBN_10 (10 characters long string)</label>
                                    <input type="text" className="form-control" id="isbn_10" placeholder="Enter ISBN 10" name="isbn_10" value={this.state.book.isbn_10 != null ?this.state.book.isbn_10:''} onChange={this.handleChange}/>
                                </div> 

                                <div className="form-group">
                                    <label htmlFor="title">Title</label>
                                    <input type="text" className="form-control" id="title" placeholder="Enter Title" name="title" value={this.state.book.title != null ?this.state.book.title:''} onChange={this.handleChange}/>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="description">Description</label>
                                    <textarea type="text" className="form-control" id="description" placeholder="Enter description" name="description" onChange={this.handleChange} value={this.state.book.description != null ?this.state.book.description:''} rows="6">
                                    </textarea>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="author">Author</label>
                                    <input type="text" className="form-control" id="author" placeholder="Enter Author" name="auhtor" value={this.state.book.author != null ?this.state.book.author:''} onChange={this.handleChange}/>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="publisher">Publisher</label>
                                    <input type="text" className="form-control" id="publisher" placeholder="Enter Publisher" name="publisher" value={this.state.book.publisher != null ?this.state.book.publisher:''} onChange={this.handleChange}/>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="page_count">Pages</label>
                                    <input type="text" className="form-control" id="page_count" placeholder="Enter Pages" name="isbn" value={this.state.book.page_count != null ?this.state.book.page_count:''} onChange={this.handleChange}/>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="date_of_purchase">Date of purchase</label>
                                    <input type="text" className="form-control" id="date_of_purchase" placeholder="Enter Date of purchase" name="date_of_purchase" value={this.state.book.date_of_purchase != null ?this.state.book.date_of_purchase:''} onChange={this.handleChange}/>                     
                                </div>

                                <div className="form-group">
                                    <label htmlFor="first_published">First Published</label>
                                    <input type="text" className="form-control" id="first_published" placeholder="Enter First Published" name="first_published" value={this.state.book.first_published != null ?this.state.book.first_published:''} onChange={this.handleChange}/>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="classification">Classification</label>
                                    <input type="text" className="form-control" id="classification" placeholder="Enter ISBN" name="classification" value={this.state.book.classification != null ?this.state.book.classification:''} onChange={this.handleChange}/>
                                </div>

                                <div className="form-group">
                                    <label htmlFor="genre">Genre</label>
                                    <input type="text" className="form-control" id="genre" placeholder="Enter Genre" name="genre" value={this.state.book.genre != null ?this.state.book.genre:''} onChange={this.handleChange}/>
                                </div>



                                <div className="form-group">
                                    <button type="submit" className="btn btn-primary">Update</button> &nbsp;&nbsp;&nbsp;&nbsp;
                                    <button type="button" className="btn btn-danger">Delete</button>
                                </div>    
                            </form>
                        </div>    
                    </div>
                </div>
        </section>    

        );
    }
};

export default UpdateBook;
3
  • I think scoping is your issue. using then, you get into another scope level where this.setState doesn't exist. A way to solve it is to write let that = this in your top handleSubmit scope, and refer to that inside the next scope, i.e. that.setState. Not sure if it's best practice(anyone else can chime in), but should work. Commented Dec 20, 2017 at 14:58
  • @cbll No, since he is using arrow functions, his scope will stay in the component this# Commented Dec 20, 2017 at 14:59
  • Yes, you are correct :) Commented Dec 20, 2017 at 15:00

1 Answer 1

2

I think you want to call setState in handleChange:

 handleChange(e) {
       console.log(this.state.book[e.target.name]); 
       this.setState({ book[e.target.name]: e.target.value });

       console.log(this.state.book[e.target.name]); 
    }
Sign up to request clarification or add additional context in comments.

2 Comments

that's actually quite intresting that the OP uses setState everywhere, except here, maybe you could tell him why manually mutating state is not an option here ;)
@brub Icepickle thanks for finding the issue. I am kind of ashamed that I did that mistake :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.