"Create a separate function for the pipeable operator in RXJS for enhanced code

After working on some code, I came up with the following implementation

this.form.valueChanges.pipe(
    take(1),
    map(val => // doSomething),
    exhaustMap(val => 
      // someInner observable logic
      return of({someValue})
    )
).subscribe(finalVal => doSomething());

However, as this code is repeated in multiple components, I wanted to refactor it into an external function.

Here is what I attempted

  myExhaust(obs: Observable<any>): Observable<{ someValue: SomeClass }> {
    return obs.pipe(
      exhaustMap((val) => { 
           // do some stuff
           return of({someValue})
      })
    );
  }

Now, I am unsure of how to integrate this new function back into the original code properly (assuming the function itself is correct).

Answer №1

You're in the process of creating your own custom operator, which is a step in the right direction. To achieve this, you need to develop a function that accepts an observable and produces a new one.

function myExhaust<T>(): MonoTypeOperatorFunction<T> {
    return input$ => input$.pipe(
       exhaustMap((val) => { 
           // perform some operations
           return of({someValue})
       }))
}

Subsequently, you can integrate myExhaust into your pipe instead of using exaustMap.

Answer №2

It appears that your tool is functioning correctly, and below is how you can transmit the tool to the pipeline:

this.manager.valueChanges.pipe(
capture(1),
 myExhaust,
).subscribe(result => performAction());

Check out a functional demonstration here

Answer №3

If you want to implement a shared function that can be used in various components, you can create a generic function with the desired logic:

// Define appropriate types for your function
// This is just an example
export function customFunction<T>(data: T): Observable<T> {
  // Add your custom logic here
  return of<T>(data);
}

// Implementation example
this.form.valueChanges
  .pipe(
    take(1),
    map(val => /* do something */ ),
    exhaustMap(val => customFunction(val))
  )
  .subscribe(finalVal => /* do something else */ );

If you specifically need to pair this function with the exhaustMap operator, then you will require a custom pipeable operator.

Answer №4

To combine existing operators, you can utilize the pipe function:

import { pipe } from 'rxjs';
import { filter, map } from 'rxjs/operators';

function excludeOddDuplicateEven() {
  return pipe(
    filter((v) => !(v % 2)),
    map((v) => v + v)
  );
}

For more details, please consult the official documentation: https://rxjs.dev/guide/operators#use-the-pipe-function-to-make-new-operators

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

Memory Leak in Angular's Chain of mergeMap and concatMap Functions

I am facing an issue where a memory leak is being caused for each processed file during the upload of a 1 TB folder to Blob Storage. I have implemented a parallel processing pipeline using mergeMap to handle the files through a series of steps with concatM ...

Converting a string into a TypeScript class identifier

Currently, I am dynamically generating typescript code and facing an issue with quotes in my output: let data = { path: 'home', component: '${homeComponentName}', children:[] }; let homeComponentName = 'HomeComponent' ...

The Angular application shell build has produced two new folders within the dist directory. I'm curious about their purpose and how they can

Whenever I execute the ng run my-app:app-shell -c production command, it creates 2 folders within the dist directory - one for the browser and one for the server. Now, I find myself with 2 different commands to use: npm build --prod (for a regular build) ...

"Revolutionizing the way we navigate: Angular's innovative

Presently, my focus is on incorporating route transitions into my project. I've employed a component that appears on click and triggers the corresponding service function: routeTransition(destination) { if (this.router.url !== destination) { t ...

Resolve the upstream dependency conflict that occurs during the installation of ng-bootstrap/ng-bootstrap

Encountering an error while attempting to install npm install --save @ng-bootstrap/ng-bootstrap. Seeking assistance in resolving this issue. npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: <a ...

Combining the Partial<CssStyleDeclaration> union type with a dictionary can lead to potential typing complications when the implicit any flag is

Using VueJS v-bind:style binding makes it possible to set CSS variables. I am attempting to create a union type that allows for the object passed to v-bind:style to retain typings for CssStyleDeclaration, while also being relaxed enough to accept an arbitr ...

Issue with dynamic HTML preventing Bootstrap tooltip functionality

There's an HTML page where a section is dynamically generated through HTML injection from a typescript angularjs controller using $sce and ng-bind-html. The issue is that the custom bootstrap tooltip style doesn't seem to be applied, and only t ...

Using an angular 4 static method with a non-static object as an argument

Currently, I am working on an Angular 4 application and facing an issue while trying to pass the current language to the toLocaleString() method. The mathRound method is static, which makes it difficult to understand this.translation.currentLang. How can ...

One way to display a table is by populating it with data from an API. If the table does

Within my Angular 6 application, there exists a table that displays data fetched from a web api. Additionally, I have incorporated some ngIf containers. One of these containers is programmed to exhibit a message in case the web api data turns out to be emp ...

The 'DOCUMENT' module (imported as 'i23') could not be located within '@angular/platform-browser'

During my upgrade from Angular version 7 to 8, I encountered an error when building the project even though I am not using DOCUMENT. It seems like something is causing this issue that I am overlooking. I have thoroughly checked all the files and confirmed ...

Utilize the failure of Travis due to issues with a Git submodule to improve

I am facing an issue with my Angular project that has a git submodule for the backend. When I build the project on my local machine, it is successful. However, when I try to build it on Travis, it fails. npm ERR! enoent ENOENT: no such file or directory, ...

Using Angular to declare a variable for reuse within nested HTML elements

Exploring the realm of angular development has sparked my interest, however, I found myself at a roadblock while reading through the documentation. The issue lies in figuring out how to declare a variable that can be reused effectively within nested HTML e ...

Is there any benefit to making the SVG elements width and height 100%?

The Angular Material documentation app features an SVG Viewer that is able to scale the SVG content to fit the container using the following function: inlineSvgContent(template) { this.elementRef.nativeElement.innerHTML = template; if (this.sca ...

What is the best way to implement multiple HTTP subscriptions in a loop using Angular?

I find myself in a predicament where I need to iterate through an array of strings passed as parameters to a service, which then responds through the HTTP subscribe method. After that, some operations are performed on the response. The issue arises when t ...

Debate surrounding the use of .next() in conjunction with takeUntil

Recently, I've observed a change in behavior after updating my rxjs version. It seems that the .next() method this.ngUnsubscribe$.next(); is no longer functioning as it used to: export class TakeUntilComponent implements OnDestroy { // Our magical o ...

Is the Angular custom validator failing to trigger if the input is left untouched?

My form setup is as follows: this.form = this.formBuilder.group({ name: ['', Validators.required], email: ['', this.customValidator()] }); I have a button labeled "submit" with a condition for disabling: <button [disabled]=" ...

Struggling to find a way to make Istanbul disregard the Angular @Input set function

I'm having trouble figuring out how to ignore a specific input set function in ng2. Can anyone provide guidance on this issue? Thanks! /* istanbul ignore next */ @Input() set pageOffset(pageOffset: number) { this.pageOffsetSetter(pageOffset); } ...

Angular - The element contains an implicit 'any' type due to the absence of an index signature in the 'AbstractControl' type

Within my Angular-11 project, I am utilizing the following TypeScript code: multistep = new FormGroup({ userDetails: new FormGroup({ first_name: new FormControl(''), last_name: new FormControl(''), other_na ...

Rearrange the layout by dragging and dropping images to switch their places

I've been working on implementing a photo uploader that requires the order of photos to be maintained. In order to achieve this, I have attempted to incorporate a drag and drop feature to swap their positions. However, I am encountering an issue where ...

tips for concealing the shadow of a draggable div during the dragging process

I am facing an issue with a draggable div. When I drag the div, the shadow also moves along with it. I want to find a way to hide this shadow while dragging. <div draggable="true" (dragstart)="mousedown($event)" (drag)="dra ...