Guilherme Lucas
Guilherme Lucas

Reputation: 517

Validation of an observable response before registration to perform multiple requests(iff) - RxJs

I have a method that makes requests to the server while the field hasProcessado (hasProcessed in english) is false, if it is true, it should stop making new requests. A maximum of 10 requests are made, in case of error it makes only 3 requests.

But in server, even when hasProcessado == true it keeps making requests. Doing local tests works normally

public pullingPerfilInvestor(): Observable<any> {
    let result = this.http.get<PerfilInvestor>(this.configService.generateNewUrl(`${environment.api.endpoints.obterPerfil}`), { headers: this.configService.concatenateHeaders(true) })
    return result
      .pipe(
        concatMap(res => iif(() => res.hasProcessado,
          of(res),
          interval(500).pipe(
            take(9),
            concatMap(() => result)
          )
        )),
        catchError(err => {
          return throwError(err);
        }),
        retryWhen(errors =>
          errors.pipe(
            delayWhen(val => timer(500)),
            concatMap((error, index) => {
              if (index === 2) {
                return throwError(error)
              }
              return of(null);
            }),
            take(3)
          )
        ),
        shareReplay(1),
        last()
      );
  }

My Object in SoapUi:

{
    "perfil": {
        "hasPerfil": true,
        "descricao": "Arrojado",
        "aderencia": {
            "exibirMensagem": true}
        },
    "questionario": {
        "vencimento": "01.12.2021",
        "isVencido": false
        },
        "hasProcessado": false
}

In my browser local, makes the 10 requests because in soapUi the hasProcessado == false:

enter image description here

While hasProcessed is false:

enter image description here

After hasProcessado is true, it keeps making requests

enter image description here

My object in server:

{
   "hasProcessado":true,
   "dataPosicao":null,
   "perfil":{
      "hasPerfil":true,
      "descricao":"Arrojado",
      "aderencia":{
         "isExibirMensagem":false
      }
   },
   "questionario":{
      "vencimento":"15.06.2022",
      "isVencido":false
   }
}

OBS: I believe it's something with concatMap and iff.

Upvotes: 0

Views: 246

Answers (1)

chewie
chewie

Reputation: 333

You are using the take operator the wrong way. The code below is great but works the way you need it:

  • Performs pulling conditionally on the result of the request;

  • Performs 3 more pullings if the request is successful

      public pullingPerfilInvestor() {
          let countTimes = 0;
    
      interval(500)
        .pipe(
          concatMap(() => this.http.get<PerfilInvestidor>(this.configService.gerarUrlNovo(`${environment.api.endpointsNovos.obterPerfil}`), { headers: this.configService.concatenarHeaders(true) })),
          filter((data: PerfilInvestidor) => {
            countTimes = countTimes + 1;
            return data.hasProcessado === true || countTimes == this.MAX_PULLING;
          }),
          catchError(err => {
            return throwError(err);
          }),
          retryWhen(errors =>
            errors.pipe(
              delayWhen(val => timer(500)),
              concatMap((error, index) => {
                if (index === 2) {
                  return throwError(error)
                }
                return of(null);
              }),
              take(3)
            )
          ),
          take(1),
          shareReplay(1),
          last()
        )
        .subscribe(response => {
          this.perfilSubject.next(response)
        }, error => {
          this.perfilSubject.error(error);
        });
    }
    

Upvotes: 1

Related Questions