0

The following is my handleSubmit function which is fired when the form full of questions is submitted. The trouble is, even if all 21 questions are answered, filledAll does not change to true. But when I click submit for the second time, filledAll is set to true.

handleSubmit(event){
        event.preventDefault();
        let sum = 0;
        this.state.score.forEach(function(value, index){
            if (value !== undefined) {
                sum += Number(value);
            }
        });
        console.log(sum);

        if (this.state.score.length === 0) {
            this.setState({filledAll: false});
            console.log('Scroll to question 1')
            this.doScrolling("#question-1", 1000)
        } else {
            for (let i = 1; i <= 21; i++) {
                console.log('Score of all 21 questions', this.state.score[i]);
                // wherever the score is undefined
                if (this.state.score[i] === undefined) {
                    console.log('if score is undefined, set filledAll to false.')
                    this.setState({filledAll: false});

                    console.log('Scroll to #question-' + i)
                    this.doScrolling("#question-" + i, 1000)
                    break;
                }
                else {
                    this.setState({filledAll: true});
                    console.log('else block', this.state.filledAll);
                    localStorage.setItem('total', sum)
                    // window.location.replace("/index");
                }
            }
        }
    }

I am using filledAll so I could know when all the questions are answered and to redirect to another page when it is true.

Harish
  • 490
  • 2
  • 11
  • 19

2 Answers2

1

I wouldn't use state for filledAll as it shouldn't re-render the component.

I would suggest something like -

handleSubmit(event){
        event.preventDefault();
        let sum = 0;
        let filledAll = true;
        this.state.score.forEach(function(value, index){
            if (value !== undefined) {
                sum += Number(value);
            }
        });
        console.log(sum);

        if (this.state.score.length === 0) {
            console.log('Scroll to question 1')
            this.doScrolling("#question-1", 1000)
        } else {
            for (let i = 1; i <= 21 && filledAll; i++) {
                console.log('Score of all 21 questions', this.state.score[i]);
                // wherever the score is undefined
                if (this.state.score[i] === undefined) {
                    console.log('if score is undefined, set filledAll to false.')
                    filledAll = false;
                    console.log('Scroll to #question-' + i)
                    this.doScrolling("#question-" + i, 1000)
                    break;
                }
            }
        }
        
        if (filledAll) {
          console.log('filled all');
          localStorage.setItem('total', sum)
          window.location.replace("/index");
        }
    }
naortor
  • 2,019
  • 12
  • 26
  • 1
    add `filledAll = false;` inside the if block `if (this.state.score.length === 0)` and it works perfectly. – Harish Dec 31 '19 at 15:26
  • 1
    you can also live without the filledAll at all, if when ever you find a score that wasn't filled up you can just break out from the function `return;`. it will be more readable imo. – naortor Dec 31 '19 at 15:36
0

this.setState is an asynchronous function. So updation of state will only happens eventually. In your case the code below the this.setState will run immediately after this.setState is invoked. By moving your code below this.setState to the call back of this.setState will do the work.

handleSubmit(event){
    event.preventDefault();
    let sum = 0;
    this.state.score.forEach(function(value, index){
        if (value !== undefined) {
            sum += Number(value);
        }
    });
    console.log(sum);

    if (this.state.score.length === 0) {
        this.setState({filledAll: false}, () => {
            console.log('Scroll to question 1')
            this.doScrolling("#question-1", 1000)
        });
    } else {
        for (let i = 1; i <= 21; i++) {
            console.log('Score of all 21 questions', this.state.score[i]);
            // wherever the score is undefined
            if (this.state.score[i] === undefined) {
                console.log('if score is undefined, set filledAll to false.')
                this.setState({filledAll: false}, () => {
                    console.log('Scroll to #question-' + i)
                    this.doScrolling("#question-" + i, 1000)
                });
                break;
            }
            else {
                this.setState({filledAll: true}, () => {
                    console.log('else block', this.state.filledAll);
                    localStorage.setItem('total', sum)
                    // window.location.replace("/index");
                });
            }
        }
    }
}
k1r4n
  • 159
  • 6