Nauruto
Nauruto

Reputation: 153

Uncaught ReferenceError in React project

I'm working on a tiny project for learning React and I got stuck.

My problem: When a post request called, I get: "Uncaught ReferenceError: val is not defined". Someone can figure out why??

In addition, I want the ul to re-render every new post created. If I changed this:

handleSend(msg){
        this.state.val.push(msg);
        this.setState({val});
    }

to this:

handleSend(msg){
        this.state.val.push(msg);
        this.setState({val: []});
    }

I don't get any errors but i need to refresh the page to see the new post on the ul.

This is my code: Hope you guys can figure it out and help me :)

  class CoachPage extends React.Component {

  constructor(props, context) {
    super(props, context);
    this.state={
      val: []
    };
  }

  handleSend(msg){
    this.state.val.push(msg);
    this.setState({val});
}

componentDidMount(){
  fetch('http://localhost:3003/api/msgs/')
    .then( res => res.json())
    .then( data => this.setState({ val: data }))
    .catch( console.error ); 
}

 deleteMsg(id){
    return fetch('http://localhost:3003/api/msgs/' + id, {
      method: 'DELETE'
    })
      .then(response =>
        response.json()
      .then(json => {
        return json;
      })
    );
  }

  render() {
    return (
      <div className="container"  style={{color: '#FFF', textAlign: 'right'}}>
        <h1>Coach Page</h1>
        <AddMsg onSend={this.handleSend.bind(this)}/>
        <Panel header="עדכונים" bsStyle="info" style={{float: 'left', textAlign: 'right', width: '40em'}}>
        <ul id="coach-panel-content">
        { 
          this.state.val.map( (msg, index) =>
            <li dir="rtl" key={index} className='myli'>
              {msg.msgdata}
              <span onClick={() => this.deleteMsg(msg._id)}>X</span>
              <hr/>
            </li>
          )
        }
        </ul>
        </Panel>
      </div>
    );
  }
}

export default CoachPage;

Upvotes: 1

Views: 1456

Answers (2)

Jonathan Dion
Jonathan Dion

Reputation: 1671

Updated

You had some problems:

  • val was undefined because you never assigned a value to it
  • msg is a String not an Object. In your render method you access to an Object {msg.msgdata}

val is undefined because you don't assign any value to it.

{ val; } // not defined vs { val : "Message" } //defined

handleSend(msg){
 this.setState(prevState => ({val: [...prevState.val, { msgdata: msg }] }));
}

I think you misunderstood the destructuring assignment

Upvotes: 2

dashton
dashton

Reputation: 2714

There are no guarantees about when setState gets executed, so you are better using the version of setState that takes an update function; the first parameter of which is your current (up to date) state:

handleSend(msg) {
    this.setState((prevState, props) => {
      return {val: [...prevState.val, msg]};
    });
}

Upvotes: 0

Related Questions