Incorporate real-time validation observables with the power of rxjs

Currently, I am working on implementing an observable for a validation task. There are 2 observables, frontEndValidate and backEndValidate, which I need to process sequentially in a specific order. If any of these observables throws an error, the entire pipeline should stop. These observables will be emitted at runtime when the user clicks on the validate button by calling the next() function inside the validate() method.

Within the pipeline, I validate the emitted values from the observables. If the values are valid, the pipeline continues; otherwise, an error is thrown.

Currently, everything works as expected if both observables emit of({ valid: true}). However, if either one emits of({valid:false}), my validationAction$ stream stops functioning, and the validate button becomes unresponsive.

The issue with using catchError to handle errors is that it would not prevent the validation from continuing regardless of the state of the observables.

In summary, I want the pipeline to follow these rules and remain active:

  1. If both validations are successful: from([true,true])
  2. If one validation fails: from([true, false])
  3. If both validations fail: from([false])

Thank you for your help.

Pipeline

private validationSubject = new Subject<Observable<any>>();
validationAction$ = this.validationSubject.asObservable().pipe(
    concatMap((item) =>
        from(item)
            .pipe(
                map((result) => {
                    console.log("result", result);
                    if (!result.valid) throw new Error();
                    return result
                }),
            )
    ),
);

onClick

validate() {
    this.validationSubject.next(this.frontEndValidate());
    this.validationSubject.next(this.backEndValidate());
}

2 Observables

/* Front-end validation */
/** */
frontEndValidate(): Observable < any > {
    // Validation goes here

    return of({ valid: true, name: 'frontend', msg: 'Passed' }).pipe(
        tap(() => {
            console.log('frontend validation...starts');
        }),
        delay(3000), // mimic delay
        tap(() => {
            console.log('frontend validation...finished')
        }),
    );
}

/* Back-end validation */
/** */
backEndValidate(): Observable < any > {
    // Validation goes here 

    return of({ valid: true, name: 'backend', msg: 'Passed' }).pipe(
        tap(() => {
            console.log('backend validation...starts');
        }),
        delay(3000), // mimic delay
        tap(() => {
            console.log('backend validation...finished')
        }),
    );
}

Answer №1

Have you considered implementing it this way:

  validate() {
    const result$ = combineLatest([
      this.frontEndValidate(),
      this.backEndValidate(),
    ])
      .pipe(
        tap(([frontEndResult, backEndResult]) => {
          // Additional operations can be performed here
        })
      );

    result$.subscribe(x => console.log('Final Result: ', JSON.stringify(x)));
  }

In this approach, you can do away with the subject and utilize combineLatest to merge the results of both validations and make sure that the subsequent code waits for both to finish before proceeding.

The outcome will be an array containing the two objects defined in your validation methods. To modify this to emit only an array of Boolean values, you can try the following modification:

  validate() {
    const result$ = combineLatest([
      this.frontEndValidate(),
      this.backEndValidate(),
    ]).pipe(
      map(([frontEndResult, backEndResult]) => 
        ([frontEndResult.valid, backEndResult.valid])
      )
    );

    result$.subscribe((x) => console.log('Final Result: ', JSON.stringify(x)));
  }

For a demonstration, refer to this working example: https://stackblitz.com/edit/angular-rxjs-validation-deborahk

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

Shifting the placement of a component in Vue JS when hovering the mouse

I am facing an issue regarding the positioning of components. I have four images, and when you hover over them, a specific component is displayed as shown below: https://i.sstatic.net/gybcy.png For example, hovering over a yellow image will display a dif ...

Ensure that the JavaScript file is fully loaded and that the JavaScript function has been properly initiated prior to executing any additional

Having an issue with a tracking code not working properly as it is called before a required JS script and function is loaded. The situation is as follows: Upon successful form submission (CF7 on WordPress), the following function is immediately called. ...

There is a delay in updating ng-if/ng-hide in real time on the HTML page

Assistance needed for implementing a slight adjustment in AngularJS with TypeScript. The requirement is to change the text of a button for 3 seconds upon clicking, then revert back to its original text. Two HTML elements are created for this purpose, each ...

Issue with opening image modal when clicking on images, JavaScript seems to be malfunctioning

I created a gallery of modal images that I want to open when clicked, but for some reason it's not working as expected. What I'm trying to achieve is passing the image ID of each image to JavaScript when they are clicked so that the script can th ...

What is the best way to adjust a wide HTML table to make it narrow enough to fit perfectly within the screen width?

I need assistance with formatting an HTML table that contains multiple columns: <table id="req_header" border="2" style="overflow: auto;"> <tr> <th><i class="fa fa-solid fa-check"> ...

The problem persists as Vite is failing to load CSS codes enclosed within VUE components

My project is developed using Laravel, Inertia.js with Vue, and Vite for bundling the frontend assets. Everything seems to be working fine with the application, except when I try to access it from a subdirectory. In this scenario, Vite fails to load the C ...

Is there a way to retrieve the document count on the front end by utilizing Angular Material Paginator in conjunction with a Node.js backend that is linked to a SQL database

Currently, I am struggling to nail down the logic for the paginator implementation. While I have successfully managed to retrieve and display the documents with the correct number per page, the page count seems to be stuck at 0 of 0. The database in use is ...

What steps should I take to develop an Outlook add-in that displays read receipts for action items in sent emails?

Currently, I am in the process of developing an add-in that will enable me to track email activity using a tool called lead-boxer (). With this add-in, I am able to retrieve detailed information about users who have opened my emails by sending them with an ...

Enhance the State in a React application Chrome Extension

I've developed a chrome extension with create-react-app to analyze the HTML of the current page and extract the number of relevant icons from that HTML. While I can successfully build and launch the extension in Chrome, I encounter an issue when atte ...

What is the correct way to insert a variable into a URL using a JavaScript template literal in Oracle APEX?

While attempting to create a URL in Oracle APEX JavaScript using a template literal, I encountered an issue where the variable was not interpolated correctly. Rather than obtaining the expected URL, the variable name appeared distorted. Here is what I am ...

"VS Code's word wrap feature is beneficial for wrapping long lines of text and code, preventing them from breaking and ensuring they are

text not aligning properly and causing unnecessary line breaks insert image here I attempted to toggle the word wrap feature, installed the Rewrap plugin, and played around with vscode settings ...

Adding images to HTML using JavaScript below existing images

I'm currently working on a JavaScript game and I want to implement a feature where my character can move under blocks (isometric PNG images) instead of just sliding through them. Is there a way to dynamically adjust my character's position in the ...

"Encountering a Problem with Assigning Variables in Vue

My issue revolves around the integration of VueJs, Vue-Resource, and Laravel. The problem occurs when attempting to assign a local variable to response data received from an AJAX request using vue-resource. Code Javascript <script> flags_ ...

Is there a method to avoid redeclaring variables in JavaScript with jQuery?

In the structure of my code, I have the following setup. <!-- first.tpl --> <script> $(document).ready(function() { objIns.loadNames = '{$names|json_encode}'; } ) </script> {include file="second.tpl"} <! ...

What is the process of adding information to a JSON file?

I'm looking to store my data in an external JSON file and have it update the list when the page is reloaded. Can anyone assist with this? Below is my code: $scope.addUser = function() { var user = { id: null, login: '', ...

Ways to utilize a single HTML page for various URLs while changing one variable value based on the queried URL

My current HTML page structure looks like this: <body ng-controller="DashboardDisplay" onload="submit()"> <div class="container-fluid" > {{scope.arr}} </div> </body> <script> var myApp = angular.module(&apos ...

The command "ng server" encountered an EACCES error, indicating that permission was denied to listen on 127.0.0

Running ng serve on 127.0.0.1:4200 has always worked fine for me. However, today when I tried to run ng serve, I encountered an error: An unhandled exception occurred: listen EACCES: permission denied 127.0.0.1:4200 Is there a permanent solution to this ...

Uploading custom images with a WordPress widget

I have been occupied with developing my own WordPress Widget, and almost everything is functioning smoothly except for the WordPress media uploader. I have incorporated eight buttons and input text fields to store the URL of the uploaded image. The click ...

Switching sub components based on routing through navigation links after logging in

I'm having an issue with my routing setup while transitioning from the login page to the main page. Here's how my Routes are structured: App.jsx <BrowserRouter> <Routes> <Route path="/main/" element={<Main ...

How can I send back multiple error messages from a pug template in a node.js application with Express?

I am currently working on validating inputs from a form on a Node.js web server using Pug.js and Express.js. The issue I am facing is that when there are multiple problems with the user's input, only the first error is displayed to the user. How can I ...