Is there a more efficient way to write the code below using MergeMap or FlatMap or other rxJs operators?

I have a situation where I have two observable pipes and I need to run them one after the other in order to compare their emitted values. The code snippet I attempted is provided below. Ideally, when the first observable emits a value, it should then fetch the second observable's value and compare it with the first one. I believe there might be room for improvement in this code and would appreciate any expert help in refactoring it more efficiently.

   this.selectedUnitDetailModel$.pipe(shareReplayUntil(this.destroySub)).subscribe(
          (res: UnitDetail) =>{
              if(res.unitTwo){
                this.appStore.select(selectUnit).
                pipe(shareReplayUntil(this.destroySub)).subscribe(
                  (unitId: string) => {
                    if(unitId ===  res.unitTwo){
                      this.sameUnit = true;
                    }else{
                      this.sameUnit = false;
                    }
                  });
              }
          }
       );

Answer №1

Higher order operators are unnecessary in this scenario as the observables this.selectedUnitDetailModel$ and this.appStore.select(selectUnit) operate independently. Instead, consider using functions such as forkJoin, combineLatest, or zip to process notifications from them simultaneously.

To distinguish between these functions, refer to this comparison.

Implement the following:

forkJoin(
  this.selectedUnitDetailModel$.pipe(take(1)),      // <-- complete on first emission
  this.appStore.select(selectUnit).pipe(take(1))    // <-- complete on first emission
).subscribe(
  ([res, unitId]) => this.sameUnit = res.unitTwo === unitId,
  (error) => console.log(error)                     // <-- handle error
);

forkJoin emits when the source observables complete by including take(1) for each observable. This configuration allows forkJoin to emit upon the first event of each observable and then complete, reducing the necessity for

shareReplayUntil(this.destroySub)
.

If maintaining an open emission stream from the observables is needed, consider utilizing combineLatest or zip. In such cases, replace take(1) with

shareReplayUntil(this.destroySub)
.

Update: continuous stream of this.selectedUnitDetailModel$ observable

To achieve a continuous data stream, opt for combineLatest over forkJoin.

Try this approach:

import { Subject, combineLatest } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

combineLatest(
  this.selectedUnitDetailModel$,
  this.appStore.select(selectUnit)
).pipe(
  takeUntil(this.destroySub)         // <-- replaced with `takeUntil` operator
).subscribe(
  ([res, unitId]) => this.sameUnit = res.unitTwo === unitId,
  (error) => console.log(error)                     // <-- handle error
);

Answer №2

this.selectedUnitDetailModel$.pipe(shareReplayUntil(this.destroySub),mergeMap(
          (response: UnitDetail) =>{
              if(response.unitTwo){
               return this.appStore.select(selectUnit).
                pipe(shareReplayUntil(this.destroySub),map(
                  (unitIdentifier: string) =>  unitIdentifier ===  response.unitTwo);
              }
          }
       ).subscribe({
        next: (matchingUnit: boolean) => {
           //perform a specific action 
        }
       });

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

I'm having trouble with one of my filter pipes not displaying any results. Can anyone help me troub

I have recently included a new filter for DL, but it seems that the results are not showing up as expected. Any ideas on what changes I should implement? <div class="form-group float-left mr-4"> <strong>DL</strong> <br /> ...

Show just a single error message if there are two validation errors present

In my AngularJS timepicker, users can choose multiple time segments for each day. The code has validation to detect duplicates and overlapping time segments. For example, entering 11:00am - 12:00am twice will trigger two error messages: 'Overlapping t ...

When using @Viewchild, it can sometimes lead to encountering

Within my project, I have a component called SideToggleComponent that contains a function: activeButton(value){ ... } I am trying to call this function from another component called BlogComponent. To do so, I am using @ViewChild as shown below: @ ...

I'm in the process of putting together a node.js project using typescript, but I'm a little unsure about the steps needed to

Currently, I am working on a node.js project that involves compiling with typescript. I recently realized that there is a directory named scripts dedicated to running various tasks outside of the server context, such as seed file operations. With files now ...

React hook triggering re-render

A function has been implemented to retrieve and decode user claims from a token stored in local storage using a hook. export const useActiveUser = (): { user: IUserTokenClaims | null } => { const [user, setUser] = useState<IUserTokenClaims | nul ...

Steps for setting up authentication in a Hyperledger Angular applicationAre you looking to

I successfully implemented a hyperledger composer blockchain solution across multiple organizations by following the steps outlined in this tutorial. In addition, I utilized the command yo hyperledger-composer:angular to generate an angular2 app with exis ...

Obtain the specific generic type that is employed to broaden the scope of a

I am working on a class that involves generics: abstract class Base<P extends SomeType = SomeType> { // ... } In addition, there is a subclass that inherits from it: class A extends Base<SomeTypeA> { // ... } I'm trying to figure out ...

Creating Angular components and attaching them to the body tag is a simple yet

My goal is to create a component at the root element of the page. I have come across some resources that are similar to what I need, but they use the DynamicComponentLoader which is now considered deprecated. public component: any; constructor( public ...

What is the process for importing a function dynamically in a Next.js TypeScript environment?

Currently, I am utilizing a React modal library known as react-st-modal, and I am attempting to bring in a hook named useDialog. Unfortunately, my code is not functioning as expected and appears like this: const Dialog = dynamic<Function>( import(& ...

Angular-meteor tutorials have a method known as '/parties/insert' that is already clearly defined and explained

I am currently diving into meteor + angular and enjoying learning through ! As I was working on the 3-way data binding section, I created a folder named collections within the socially folder. In this folder, I made a file called parties.ts where I added ...

Angular animation not firing on exit

I am encountering an issue with my tooltip component's animations. The ":enter" animation is working as expected, but the ":leave" animation never seems to trigger. For reference, here is a link to stackblitz: https://stackblitz.com/edit/building-too ...

What are some techniques to ensure null checking is enforced for objects that are nested within multiple layers

Currently, I am leveraging redux sagas to fetch data asynchronously from various endpoints using a unified interface: export interface ResponseInfo { data?: any; status: number; headers?: any; subCode?: string; } To ensure that null check ...

typescript component parameter function causing alert

I am encountering an issue with the following code snippet: <GoogleLogin onSuccess={responseGoogle => { const { email, name } = responseGoogle.profileObj; // error: Property 'profileObj' does not exist on type 'GoogleLoginRespon ...

Obtaining JSON data in React Native without prior knowledge of the key

When I receive this type of data, the keys are common but the items vary. How can I extract and add this data to my list of categories? { "99": "Venues", "100": "Party Supplies", "101": "Enter ...

"Error encountered while executing a code snippet using Navalia in TypeScript

I have been attempting to execute this code snippet from https://github.com/joelgriffith/navalia but despite my efforts, I have not been able to get it running smoothly without encountering errors: navaliatest.ts /// <reference path="typings.d.ts" /&g ...

What is the method for incorporating dynamic query parameters using strings in Angular 7?

I am currently faced with the challenge of having multiple dropdown fields on my screen. When a dropdown value is selected, I need to pass it in the query parameter to create a dynamic query parameter. However, the code I have tried so far does not seem to ...

Compiling TypeScript files into multiple JavaScript files using Visual Studio 2015 Update 1

I am working on a project that involves multiple Typescript files and I am trying to find a way to compile specific groups of these files into separate JS files. For example: Scripts\Group1\file1.ts Scripts\Group1\file2.ts Scripts&bso ...

Ways to fill the option selections using the service

I am currently working on an Angular application where I need to populate dropdown lists from backend data. .component.ts public getMemberCodes() { let baseUrl = `/endpoindAPI`; this._restfulService .restfulGetData(baseUrl) .subscribe( ...

Moving information from two modules to the service (Angular 2)

Recently in my Angular2 project, I created two components (users.component and tasks.component) that need to pass data to a service for processing before sending it to the parent component. Code snippet from users.component.ts: Import { Component } fro ...

Error in VS2015 when attempting to assign a two-dimensional array in TypeScript build

I've run into some build errors in my TypeScript project in Visual Studio 2015. Despite the application working fine in the browser, I'm unable to publish it due to these errors. export var AddedFields: Array<Array<Field>[]>[]; myGl ...