Search code examples
javascriptangularrxjs

RxJs requests in cycle


I have a list of parameters and for each parameter a request is sent to the server. The number of parameters may vary, so requests are sent in a loop. The question is, how can I send requests for all parameters, wait for a response from all requests and continue executing the program. To do this you need to use RxJS.

  private getValuesForEditTariff(parameter: Parameter) {

    if (parameter.dependParams != null && parameter.dependParams.length > 0) {

      let pars: Parameter[] = new Array<Parameter>();
      this.actionEditTariff.groups.forEach(group => {
        pars = pars.concat(group.parameters);
      });

      let locator = (p: Parameter, id: number) => p.id == id;

      let service = this.actionService;
      let action = this.actionEditTariff;

      parameter.dependParams.forEach(parameter => {

        let par = pars.find(p => locator(p, parameter));
        if (par) {

          par.loading = true;

          service.getValues(parameter, pars,action.action, action.actionScheme).subscribe({
            next: (data) => {
              par.values = data;
              par.loading = false;
              console.log("Значения получены");
            },
            error: (error)=> {
              this.message = error.error.message || error.statusText;
              par.loading = false;
              this.showError();
            }
          })
        }
      })
    }
  }

I tried to use concatMap, but i dont fugire out how its works


Solution

  • You can use forkJoin to wait for all the responses like this

    private getValuesForEditTariff(parameter: Parameter) {
      if (parameter.dependParams != null && parameter.dependParams.length > 0) {
        let pars: Parameter[] = new Array<Parameter>();
    
        this.actionEditTariff.groups.forEach(group => {
          pars = pars.concat(group.parameters);
        });
    
        const locator = (p: Parameter, id: number) => p.id == id;
    
        const service = this.actionService;
        const action = this.actionEditTariff;
    
        const parameters$ = parameter.dependParams.reduce((parameters, parameter) => {
          const par = pars.find(p => locator(p, parameter));
    
          if (par) {
            par.loading = true;
    
            parameters.push(
              service.getValues(parameter, pars, action.action, action.actionScheme).pipe(
                tap(() => {
                  par.values = data;
                  par.loading = false;
                  console.log('Значения получены');
                }),
                catchError(() => {
                  this.message = error.error.message || error.statusText;
                  par.loading = false;
                  this.showError();
    
                  return of(null);
                }),
              ),
            );
          }
    
          return parameters;
        }, []);
    
        forkJoin(parameters$).subscribe();
      }
    }