Checking if an observable response is valid before proceeding with registration for making multiple requests (iff) - RxJs

I have a function that sends requests to the server as long as the field hasProcessado (hasProcessed in English) is false. Once it turns true, the function should stop sending new requests. A maximum of 10 requests are allowed, but if there's an error, it will only try 3 times.

However, on the server side, even when hasProcessado == true, it continues to send requests. Strangely, local testing shows that it works correctly.

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()
      );
  }

Data Object in SoapUi:

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

In my local browser, it makes 10 requests because in SoapUi hasProcessado == false:

https://i.sstatic.net/74V8M.png

While hasProcessed is false:

https://i.sstatic.net/KXrwB.png

Once hasProcessado changes to true, it continues to make requests.

https://i.sstatic.net/15Gv2.png

Data Object in the server:

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

NB: I suspect there might be an issue with the concatMap and iff logic within the code.

Answer №1

It appears that the take operator is being misused in your code. Below is a corrected version of the code that should function as expected:

  • Conditionally performs pulling based on the result of the request;

  • If the request is successful, it performs 3 additional pullings

      public performInvestorProfilePulling() {
          let countTimes = 0;
    
      interval(500)
        .pipe(
          concatMap(() => this.http.get<InvestorProfile>(this.configService.generateNewUrl(`${environment.api.newEndpoints.retrieveProfile}`), { headers: this.configService.concatenateHeaders(true) })),
          filter((data: InvestorProfile) => {
            countTimes = countTimes + 1;
            return data.hasCompleted === 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.profileSubject.next(response)
        }, error => {
          this.profileSubject.error(error);
        });
    }
    

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to identify unauthorized utilization of web APIs within TypeScript?

Recently, I encountered an issue while using the URLSearchParams.size in my code. To my surprise, it didn't work on Safari as expected. Checking MDN's browser compatibility table revealed that Safari version 16.6 does not support this feature, un ...

Having trouble with transferring JSON data as a string from POSTMAN to a node server

My JSON data structure is as follows: const json = { "name": "Peter", "age": 21 } After calling JSON.stringify(json), the result is: '{"name":"Peter","age":21}' I am currently us ...

Creating a JSON data array for Highcharts visualization: rearranging values for xAxis and columns

I am facing an issue with my column chart where JSON data is being parsed in the "normal" form: Years are displayed on the xAxis and values on the yAxis (check out the fiddle here): array( array( "name" => "Bangladesh", ...

I am facing an issue with Lotties having a black background in my NextJS project. Is there a way to make them transparent

I am facing an issue with my LottieFiles (JSON) displaying a black background when imported into my NextJS project. Despite trying to set background='transparent' on both the Player and parent div, the problem persists. I made sure to export my ...

Linking together or organizing numerous JavaScript function executions in instances where the sequence of actions is crucial

I have implemented a web api method that conducts calculations by using a json object posted to the method. I believe that a jquery post is asynchronous. Assuming this, I want to be able to link multiple calls to the js function invoking this api method in ...

Row within a table displaying link-like behavior

Here is the code I'm currently using: $('.table-striped tr').click( function() { var link = $(this).find('a').attr('href'); if(link != 'undefined') { window.location = link; } }).hover( func ...

Developing a Node.js API using Express and MySQL involves utilizing the WHERE IN clause and binding parameters with multiple comma-separated values

Having a URL structure as shown below, where multiple comma-separated values can be added to the URL: localhost:4001/api/v1/users/search?title=mr,dr This is my query implementation: router.get('/search?', function(req, res, next) { var ...

The terminal does not recognize the nodemon command

My goal is to automate server reloads using nodemon. I have successfully installed it locally and set the start command as nodemon app.js with this code: "scripts": { "start": "nodemon app.js" } Initially, everything was running smoothly. However, ...

The AJAX callback resulted in the request being aborted and the window location being

I am currently working on implementing a client-side redirect for users who are deemed invalid. The server checks if the user has access to the current page, and if not, it returns {data: 'invalid'}. In the success callback of the ajax call, I va ...

Boolean input parameter for Angular 6 element

Currently, I am in the process of developing an Angular element and providing some input parameters for it. While I have been successful in passing string input parameters such as ikrId and environment without any issues, I am facing challenges when attemp ...

Is there a way to retrieve the number of swipe up interactions from Instagram story insights using the graph API

Is there a way to retrieve the swipe up count displayed in Instagram insights? Since Facebook does not provide this data through their Graph API, how can I access it? I have already tried scraping without success and I am looking for a solution using eith ...

Is there a way to toggle or collapse a table row with a unique identifier using Angular and Bootstrap?

Currently handling Angular and Bootstrap in my work, but facing challenges with table manipulation and collapsing rows. I fetch data from a database and showcase it in a dynamically generated table using *ngFor and two rows within an ng-container. My goal ...

The issue is that the Push() function is not functioning properly when it is invoked from within

I am currently incorporating the jQuery drag and drop formbuilder plugin into my project. My goal now is to retrieve drag and drop elements from my database and integrate them into the drag and drop builder. Here is the function I am using for this reques ...

How can I set a header to be automatically included in every "render" response in Node.js/Express?

One of the challenges I face involves implementing "controllers" in my code: app.get('/',function(req,res){ var stuff = { 'title': 'blah' }; res.render('mytemplate',stuff); }); In particular, I'm worki ...

Ways to display object data in a snackbar within an Angular application

I am currently working on a snackbar feature that receives notifications from a Web Service and displays whether the Job Execution was successful or failed. To parse the JSON data, I have implemented the following code: this.messageService.messageRec ...

Next JS encountered an error - Error [ERR_HTTP_HEADERS_SENT]: It is not possible to set headers after they have already been sent to the

Having crafted a serverless application using next.js, Vercel, and Google Sheets to store customer contact data, I encountered an issue post-deployment. While my application works flawlessly locally, after deployment, I started receiving the following erro ...

When location.href is used, the page freezes up

When attempting to transition to another page by clicking on a button, I encountered an issue where the intended page would hang. The transitions to other pages worked fine, but not the specific one I needed: location.href = http://localhost:3306/mountainB ...

Is it possible that the jQuery toggleClass fade is functioning with one class but not the other?

I'm struggling to make my i elements lose the outline class on hover. However, instead of smoothly transitioning out, the class is simply lost and added back immediately. Strangely enough, when I use the same code with a background class, it works per ...

Utilizing the useState hook with generics in React for efficient data management

Utilizing a unique react hook designed to manage input validation for text fields and checkboxes, adaptable to both string and boolean values through the use of generics. An error is encountered when attempting to assign a value using setValue, displaying ...

Can we import a CSS file selectively in Vue.js?

Can specific css-files be applied only when the current route has a "forAdmin" meta in my Vue.js project that includes both an admin-panel and client pages? ...