Home > Software design >  How to update the UI after every observable finish in forkjoin on Angular?
How to update the UI after every observable finish in forkjoin on Angular?

Time:07-20

So I'm coming from this Multiple Posts call with forkjoin

in specific this code I use to make an API call:

  postdata1(body: any): Observable<any> {
    // Recieve body as a parameter
    // Declare headers here if they were special to this request in a global scope if nt
    return this.http.post(this.baseUrl   'dictionary/getrae', body, {
      headers: headers,
      responseType: 'text',
      withCredentials: true,
    });
  }

Because I've several calls (aprox 20) I want to refresh a "status bar" to know how is the % and what is the post that is completed.

So every call I made an increment on my porcentaje and change a message.
But now since I've a service attached, I can't update the interface, the refresh wait in 0% until the fork is complete and goes from 0 to 100% in nothing.

So my question is:

How can I update the interface from the service and do it in the same moment that the post ins done, and not after all post are done?

Thanks in advance

UPDATE:

The main idea is get an ui update like...
step 1 done
step 5 done
step 2 done
step 3 done
step 6 done
step 4 done
finish!

The order of the step are not important, but finish! of course has to be at the end.

This is the code that I use for forkjoin:

nuevoenviar() {
    this.palabrabuscada = $("#inputword").val();
    const body = JSON.stringify(this.palabrabuscada);

    let data1$ = this.dataService.get1(body);
    let data2$ = this.dataService.get2(body);
    let data3$ = this.dataService.get3(body);
    let data4$ = this.dataService.get4(body);
    let data5$ = this.dataService.get5(body);
    let data6$ = this.dataService.get6(body);

    return forkJoin([data1$, data2$, data3$, data4$, data5$, data6$]).subscribe((responses) => {

      this.statusfinish = "step 1...";
      this.result1 = responses[0];
      this.porcentaje  = this.porcentajeparte;

      this.statusfinish = "step 2...";
      this.result2 = responses[1];
      this.porcentaje  = this.porcentajeparte;

      this.statusfinish = "step 3...";
      this.result3 = responses[2];
      this.porcentaje  = this.porcentajeparte;

      this.statusfinish = "step 4...";
      this.result4 = responses[3];
      this.porcentaje  = this.porcentajeparte;

      this.statusfinish = "step 5...";
      this.result5 = responses[4];
      this.porcentaje  = this.porcentajeparte;

      this.statusfinish = "step 5...";
      this.result6 = responses[5];
      this.porcentaje  = this.porcentajeparte;

      this.finalizar(); // Here's where your method need to get called
    });
  }

CodePudding user response:

You could simply update the progress inside a tap for each Observable.

nuevoenviar() {
    this.palabrabuscada = $("#inputword").val();
    const body = JSON.stringify(this.palabrabuscada);

    let data1$ = this.dataService.get1(body).pipe(tap(r => {
      this.statusfinish = "step 1...";
      this.result1 = r;
      this.porcentaje  = this.porcentajeparte;
    }));
    let data2$ = this.dataService.get2(body).pipe(tap(r => {
      this.statusfinish = "step 2...";
      this.result2 = r;
      this.porcentaje  = this.porcentajeparte;
    }));
    let data3$ = this.dataService.get3(body).pipe(tap(r => {
      this.statusfinish = "step 3...";
      this.result3 = r;
      this.porcentaje  = this.porcentajeparte;
    }));
    let data4$ = this.dataService.get4(body).pipe(tap(r => {
      this.statusfinish = "step 4...";
      this.result4 = r;
      this.porcentaje  = this.porcentajeparte;
    }));
    let data5$ = this.dataService.get5(body).pipe(tap(r => {
      this.statusfinish = "step 5...";
      this.result5 = r;
      this.porcentaje  = this.porcentajeparte;
    }));
    let data6$ = this.dataService.get6(body).pipe(tap(r => {
      this.statusfinish = "step 6...";
      this.result6 = r;
      this.porcentaje  = this.porcentajeparte;
    }));

    return forkJoin([data1$, data2$, data3$, data4$, data5$, data6$]).subscribe((responses) => {
      this.finalizar(); // Here's where your method need to get called
    });
  }

The forkJoin would still wait for all Observables to finish. But keep in mind that the order is not preserved anymore. So step 6 could finish before step 1. You could use concat instead if the order is important for you.

  • Related