Roomey
Roomey

Reputation: 716

How to wait until subscribes in loop had finished?

My method

    onSubmit() {
        let answers1 = document.getElementsByName("answer");
        let answers = answers1 as unknown as HTMLInputElement;

        for (let i = 0; i < answers1.length; i++) {
            if (answers[i].checked) {
                this.dataService.getAnswerById(answers[i].value)
                    .subscribe((data: Answer) => {
                        this.sum += data["mark"];
                        console.log(this.sum);
                    })
            }
        }
        console.log(this.sum);
    }

I get all radioButtons from my document with name answer (values of this buttons are AnswerId). Then, if button is checked, I get answer by id with get method, then I take mark of this answer and add to a sum, to get whole score for a test.

answers1 are radioButton elements.

How can I get final this.sum after loop had finished? I think, I can use forkJoin, but I dont now how to use it in loops.

Upvotes: 0

Views: 115

Answers (1)

Andriy
Andriy

Reputation: 15442

try this:

import { forkJoin } from 'rxjs';

...

onSubmit() {
    // array of radio buttons
    let answers1 = document.getElementsByName("answer");
    let answers = answers1 as unknown as HTMLInputElement;

    const observables = [];
    for (let i = 0; i < answers1.length; i++) {
        if (answers[i].checked) {
            observables.push(this.dataService.getAnswerById(answers[i].value));
        }
    }

    forkJoin(observables).subscribe((data: Answer[]) => {
      this.sum = (data || []).reduce((res, ans: Answer) => res + ans.mark, 0);
      console.log(this.sum);
    });

    // at this point you cannot see this.sum as it collects async data
}

I used Array.filter() function to filter only checked answers and then Array.map() to create an array of Observables to be passed to forkJoin() function

Upvotes: 2

Related Questions