Search code examples
javascriptarraysreactjsformsreact-state-management

Adding array elements through multiple form fields in React


I am working on a quiz app project to learn to react. I came across a situation where I need to store incorrect options in a quiz question in an array. And later pass over the information to the database. This is an example JSON format.

{       
        incorrect_answers:["Jeff Bezos","Satya Nadela","Bill Gates"] }

The incorrect answer is an array and the value needs to be inputted through separate text boxes for each incorrect option like this. option input form

The part where I am stuck is appending them to the array here is my attempt.

export default class CreateQuiz extends Component{
constructor(props){
    super(props);
   
          this.onChangedIncorrectAnswer=this.onChangedIncorrectAnswer.bind(this);
    this.onSubmit=this.onSubmit.bind(this);

    this.state={
        incorrect_answers:[]
    } 
    
    
}

onChangedIncorrectAnswer(e){
    const option=e.target.value
    this.setState({
        incorrect_answers:[...this.state.incorrect_answers,option]
    });
}


onSubmit(e){
    e.preventDefault();

    const quiz = {
        incorrect_answers:this.state.incorrect_answers
    }

    console.log(quiz);
    axios.post("http://localhost:3000/quizes",quiz)
    .then(res=>console.log(res.data));
    window.location='/quiz-list';
}

render(){
    return (
        <div>
            <h3>Create New Quiz</h3>
            <form onSubmit={this.onSubmit}>
           
                <div className="form-group">
                    <label>Incorrect Option 1</label>
                    <input type="text"
                        required
                        className="form-control"
                        value={this.state.incorrect_answers[0]}
                        onChange={this.onChangedIncorrectAnswer}
                        />
                </div>

                <div className="form-group">
                    <label>Incorrect Option 2</label>
                    <input type="text"
                        required
                        className="form-control"
                        value={this.state.incorrect_answers[1]}
                        onChange={this.onChangedIncorrectAnswer}
                        />
                </div>

                <div className="form-group">
                    <label>Incorrect Option 3</label>
                    <input type="text"
                        required
                        className="form-control"
                        value={this.state.incorrect_answers[2]}
                        onChange={this.onChangedIncorrectAnswer}
                        />
                </div>

            
                <div className="form-group">
                    <input type="submit" value="Submit Quiz" className="btn btn-primary"/>
                </div>

            </form>
        </div>
    )
}

}

But the form was not working as expected. When I enter content for the first option in the "Option 1" text box only the first character is stored remaining in "Option 2" and so on.


Solution

  • try this, this would work!!

    export default class CreateQuiz extends Component {
    constructor(props) {
    super(props);
    
    this.onChangedCorrectAnswer = this.onChangedCorrectAnswer.bind(this);
    this.onChangedIncorrectAnswer = this.onChangedIncorrectAnswer.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
    
    this.state = {
      category: "",
      correct_answer: "",
      difficulty: "",
      type: "",
      question: "",
      incorrect_answers: ["", "", ""]
      };
    }
    
     onChangedCorrectAnswer(e) {
       this.setState({
      correct_answer: e.target.value
      });
     }
    
     onChangedIncorrectAnswer(e, index) {
      const option = e.target.value;
      const { incorrect_answers } = this.state;
      incorrect_answers[index] = option;
     this.setState({
      incorrect_answers
     });
    }
    
    onSubmit(e) {
      e.preventDefault();
    
    const quiz = {
      category: this.state.category,
      correct_answer: this.state.correct_answer,
      incorrect_answers: this.state.incorrect_answers,
      difficulty: this.state.difficulty,
      type: this.state.type,
      question: this.state.question
    };
    
    console.log(quiz);
    axios
      .post("http://localhost:3000/quizes", quiz)
      .then((res) => console.log(res.data));
    window.location = "/quiz-list";
    }
    
    render() {
      return (
      <div>
        <h3>Create New Quiz</h3>
        <form onSubmit={this.onSubmit}>
          <div className="form-group">
            <label>Correct Answer</label>
            <input
              type="text"
              required
              className="form-control"
              value={this.state.correct_answer}
              onChange={this.onChangedCorrectAnswer}
            />
          </div>
    
          <div className="form-group">
            <label>Incorrect Option 1</label>
            <input
              type="text"
              required
              className="form-control"
              value={this.state.incorrect_answers[0]}
              onChange={(e) => this.onChangedIncorrectAnswer(e, 0)}
            />
          </div>
    
          <div className="form-group">
            <label>Incorrect Option 2</label>
            <input
              type="text"
              required
              className="form-control"
              value={this.state.incorrect_answers[1]}
              onChange={(e) => this.onChangedIncorrectAnswer(e, 1)}
            />
          </div>
    
          <div className="form-group">
            <label>Incorrect Option 3</label>
            <input
              type="text"
              required
              className="form-control"
              value={this.state.incorrect_answers[2]}
              onChange={(e) => this.onChangedIncorrectAnswer(e, 2)}
            />
          </div>
    
          <div className="form-group">
            <input
              type="submit"
              value="Submit Quiz"
              className="btn btn-primary"
            />
          </div>
        </form>
      </div>
    );
    

    } }