How can I implement a function to execute both immediately and with a delay after a form has been changed in Angular using RxJS?

Within a component, I have implemented a form that needs to perform two actions when the values are changed:

  • Immediately update the view
  • Emit the form values to the parent component after a brief delay

The parent component contains a service tasked with making API requests upon changes in the form values. To avoid sending a request with every keystroke and thus reducing unnecessary calls, I decided to throttle the event emission.

The challenge now is managing the two separate subscribers: one for updating the view and another employing debounceTime to handle the EventEmitter:

private subscribeToChanges(): void {
  this.form.valueChanges.pipe(
    distinctUntilChanged(),
    takeUntil(this.isDestroyed$)
  ).subscribe(() => {
    this.updateView();
  });

  this.form.valueChanges.pipe(
    debounceTime(400),
    distinctUntilChanged(),
    takeUntil(this.isDestroyed$)
  ).subscribe(() => {
    this.changed.emit(this.form.value);
  });
}

In attempting to find a more elegant solution, I briefly considered adding a timeout within the initial subscriber, but it didn't feel quite right.

What would be the most appropriate approach to handling this situation?

Answer №1

To enhance your form functionality, consider utilizing the tap operator before implementing the debounceTime. See below for an example:

private handleFormChanges(): void {
  this.form.valueChanges.pipe(
    distinctUntilChanged(),
    takeUntil(this.isDestroyed$),
    tap(value => this.updateView()),
    debounceTime(400)
  ).subscribe(() => {
    this.modified.emit(this.form.value);
  });
}

Answer №2

In my opinion, there is no objectively "correct" way unless it proves to be ineffective. Here is an alternative approach.

private handleChanges(): void {
  const changesSubscription = this.form.valueChanges.pipe(
    distinctUntilChanged(),
    takeUntil(this.destroyed$)
  );

  changesSubscription.subscribe(() => {
    this.updateView();
  });

  changesSubscription.pipe(
    debounceTime(400),
  ).subscribe(() => {
    this.emitChanges(this.form.value);
  });
}

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

Issue encountered in Angular-CLI when running the command "ng e2e": inability to access localStorage in protractor tests due to ts-node limitations

In my Angular2 project, I am using ngrx and the @angular/cli: 1.0.0-beta.32.3 version. The structure of my app is very similar to the ngrx example app found at https://github.com/ngrx/example-app. I have integrated localStorage synchronization using the h ...

Tips and tricks for sending data to an angular material 2 dialog

I am utilizing the dialog box feature of Angular Material2. My goal is to send data to the component that opens within the dialog. This is how I trigger the dialog box when a button is clicked: let dialogRef = this.dialog.open(DialogComponent, { ...

Encountering a NullInjectorError while running unit tests in Angular 14 specifically related to a missing provider for Untyped

After transitioning my project from Angular 13 to Angular 14, I encountered this error message: Error: NullInjectorError: R3InjectorError(DynamicTestModule)[UntypedFormBuilder -> UntypedFormBuilder]: NullInjectorError: No provider for UntypedFor ...

Guide on generating a menu in Angular 11 using an array passed from parent to child component

I'm currently working on a menu design that includes 2 tabs. Initially, I defined an array in the parent component like this: public labelArray: string[]=['']; constructor() { this.labelArray =['tab1', 'tab2']; } N ...

How can I utilize Angular and TypeScript to loop through the innerHTML property binding effectively?

I'm currently working on using ngFor to display the binding details of the innerHtml property. <ul> <li *ngFor="let n of NotificationData"> {{n.NotificationID}} <label [innerHtml]="n.NotificationText | StyleHtml&quo ...

Is there a way to trigger the click event in the week view of an Angular 2+ calendar?

https://i.sstatic.net/Vx2x8.png HTML Templates <mwl-calendar-week-view [viewDate]="viewDate" [refresh]="refresh" (click)="weekDayClick($event)"> </mwl-calendar-week-view> In the component file weekDayCl ...

Tips for creating fixed first two columns in a table using React and TypeScript

I need a table where the first two columns stay fixed as headers while scrolling through the body of the table. ...

Tips for preventing the rxjs error "TypeError: Cannot read properties of undefined" in the Angular framework

When I try to open the page in Angular, I encounter this error: core.mjs:6485 ERROR TypeError: Cannot read properties of undefined (reading 'getDocumentContent') In my Angular component, I have an observable like this: selectedDocument$ = this.s ...

Is there a way to access the result variable outside of the lambda function?

My goal is to retrieve data from an external API using Typescript. Below is the function I have written: export class BarChartcomponent implements OnInit{ public chart: any; data: any = []; constructor(private service:PostService) { } ngOnInit( ...

Developing Unique Number Formatting in Angular 5 with TypeScript

I am in need of a solution to format numeric values in a specific way. Here is the criteria: If a number has no decimal places, leave it as is. If it has any decimal places, format it with 4 digits after the "," or "." Here are some examples: No Formatti ...

Encountering an unknown value within the inner array of a JSON response when using Angular

I received the following JSON data from an API: [ { "CinemaId": "Hfsdfsdfs", "FilmCode": "HIWdfsdfsfsf47", "FilmTitle": "BAfsdfAAR", "CinemaName": "CsfsnfsfsAhmedabad", "CinemaCity": "Ahmedabad", "CinemaLicenseName": "BIGdfsfsAh ...

Database records failing to update after deployment

After deploying my next js site using Vercel, I encountered an issue with the functionality related to adding, getting, editing, and deleting data from MongoDB. Although all functions were working perfectly locally, once deployed, I noticed that while I co ...

React Native Typescript: Issue with non-existent property

After dabbling in TypeScript for React Native, I've encountered some rather strange error messages that have me stumped. While experimenting with my code, I came across this line: <Text text={user?.last_name} style={{color:colors.textSecondary}} v ...

Disable alerts for specific files in Visual Studio 2017

I have a project that utilizes TypeScript and various external libraries. I am trying to find a solution to suppress all errors and warnings for files with the extensions .js, .ts, .d.ts, etc. located within the node_modules folder and a separate folder c ...

Step-by-step guide to setting up a customer account and adding a credit card with Stripe in an Angular Node application

I've been struggling to find a solution for creating a user and storing their credit card information in Stripe for the past day without success. After reviewing the documentation at: https://stripe.com/docs/api/customers/create const stripe = requir ...

After the installation of Storybook, there is a duplicate identifier error that arises with 'LibraryManagedAttributes'

Upon running the command npx storybook@latest init for setting up Storybook, which results in modifying package.json, I encounter an issue where I cannot run the project using npm due to: Error: node_modules/@types/react-dom/node_modules/@types/re ...

Can I perform a query on a nested map in Firestore using a domain as the key?

I have a collection for agencies in my firestore database where, in addition to other data, I am also storing domains owned by the agency. There can be multiple such domains. For example: domains: { sub.domain.com: { active: true, date_add ...

Requirements for Method Decorators - The complete path of the class module using the decorator must be provided

Upon running the decorator (method decorators) function, we are provided with access to target, methodName, and descriptor. I am seeking the module path for target in this specific scenario. Essentially, I want the file path that points to the module that ...

In Angular 14, it is crucial to remember that RxJS can only subscribe once within a single component. It is not possible to have

When using Rxjs in Angular 14, it's important to note that subscription occurs only once in a single component, not across different components simultaneously. Project Description I am currently developing a notification service for my application. ...