Tests for React challenge "Create a Controlled Form" fail

Hi

I am currently following the React course and so far completed the challenges without much problems. But at the challenge “Create a Controlled Form” I got stuck. I completed the assignment as laid out in the instruction and also the test objectives… the functionality is working fine just as instructed. But the test fails at “Typing in the input element should update the input property of the component’s state.”
However, when I manually do just that, it works fine. I am honestly out of ideas what may be wrong here. I did not change IDs, names, other elements out of the scope of the assignment etc.
Any help? Is this a bug?

Here is the code:

Code of the challenge
class MyForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      submit: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
  handleSubmit(event) {
    event.preventDefault()
    this.setState({
      submit: this.state.input
    })
  }
  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <input type="text" onChange={this.handleChange}  />
          <button type='submit'>Submit!</button>
        </form>
        <p>{this.state.input}</p>
        <h1>{this.state.submit}</h1>
      </div>
    );
  }
};

Add value={this.state.input} to your input field.

The error message is really obscure and this probably shouldn’t be a requirement in the first place.

1 Like

Ok, but what does this even accomplish? The updating of the input element is handled directly by the JS even without the explicit setting of “value”-attribute to state-attribute, isn’t it? Everything works fine without adding the “value”-attribute… so I don’t get it.

You need it to bind the input value on both ways. The way you did works because you type into the field and update the input state with the onChange listener. But what if some other thing changed the input state? In that case your field wouldn’t update, that’s why you need the value={this.state.input}, to bind it in both ways.

Let me give something so you can test it on your own, go to the challenge page and paste your own code above (the one without the fix)

In the render:

<button onClick={this.changeValue}>Change Value</button>

In the constructor:

this.changeValue = this.changeValue.bind(this);

Create a new method:

changeValue() {
    this.setState({
      input: 'Hello World'
    })
  }

Now click the Change Value button and you’ll see that the field it not updated, but the p tag is. Put our fix and you’ll see that both values are updated. :+1:

1 Like