Transforming button click from EventEmitter to RXJS observable

This is the functionality of the component utilizing EventEmitter:

import { Component, Output, EventEmitter } from "@angular/core";

@Component({
  selector: "app-my-component",
  template: ` <button (click)="clickEvent($event)">Foo</button> `
})
export class MyComponent {
  @Output()
  onClick: EventEmitter<string> = new EventEmitter<string>();

  clickEvent(): void {
    this.onClick.emit("something that comes from my.component.ts");
  }
}

@Component({
  selector: "app-root",
  template: `
    <h1>Title inside app component.</h1>
    <app-my-component (onClick)="doSomething($event)"></app-my-component>
  `
})
export class AppComponent {
  doSomething(foo) {
    console.log(foo);
  }
}

Is there a way to achieve similar functionality using an RXJS observable?

I'm attempting the following approach:

import {
  Component,
  ElementRef,
  ViewChild,
  AfterViewInit,
  Output
} from "@angular/core";
import { Observable, fromEvent } from "rxjs";
import { tap } from "rxjs/operators";

@Component({
  selector: "app-my-component",
  template: ` <button #btn>Foo</button> `
})
export class MyComponent implements AfterViewInit {
  @Output()
  onClick: Observable<string>;

  @ViewChild("btn", { static: true }) buttonRef: ElementRef<HTMLButtonElement>;

  foo$: Observable<?>;

  ngAfterViewInit() {
    this.foo$ = fromEvent(this.buttonRef.nativeElement, "click").pipe(
      tap((e) => e.stopPropagation())
    );
  }

  // what should be returned here?
  onClick(): Observable<?> {
   return this.foo$
  }
}

@Component({
  selector: "app-root",
  template: `
    <h1>Title inside app component.</h1>
    <app-my-component (onClick)="doSomething(event$)"></app-my-component>
  `
})
export class AppComponent {
  doSomething(foo) {
    console.log(foo);
  }
}

Should RXJS be used for handling a button click event?

I have read some outdated blog posts and couldn't find a comprehensive example of handling a button click event. Any guidance on this matter with a practical example would greatly assist in understanding the concept.

Answer №1

This angular implementation for handling button click events is quite unique, especially considering the use of RxJS with EventEmitter. Make sure to check out the documentation for EventEmitter here.

Since EventEmitter extends Subject, it's worth exploring direct usage of RxJS instead. For a detailed explanation, refer to this answer on Stack Overflow: Angular - Rxjs Observable - Clicking event implementation.

It's important to note that Angular discourages using native elements.

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

Storing Images in MongoDB with the MEAN Stack: A Guide using Node.js, Express.js, and Angular 6

I am currently working on developing a MEAN Shop Application, and I have encountered an error while attempting to store the product image in MongoDB. typeError: cannot read the property 'productimage' of undefined Below is the route function fo ...

Is it possible to meet the requirements of a specific interface using an enum field as the criteria?

I've been struggling to create a versatile function that can return a specific interface based on an enum argument, but all my attempts have failed. Could it be possible that I missed something or am simply approaching it the wrong way? If I try to ...

``Changing the value of a class variable in Angular 2 does not result in the

I am facing an issue with a component that contains a variable called myName export class ConversationComponent implements OnInit { private myName: string; showNames(name) { this.myName=name; } } The value is assigned using the showNames() m ...

What are some ways to customize the functionality of the data table filter in Angular Material?

Attempting to use the filter feature in Angular Material Data Table: When searching for "MATCHED", both "MATCHED" and "UNMATCHED" are displayed in the status column of the table. It seems this is due to the data object being reduced and concatenated befo ...

Collaborate on code for a cross-platform mobile application and a traditional desktop web application

I have a vision to create a cutting-edge app that can be utilized as both a hybrid mobile application and a desktop web application. For the most part, the logic and user interface will remain consistent across both versions. However, there are a few key ...

Challenges encountered when setting a value to a custom directive via property binding

I'm working on a question.component.html template where I render different options for a specific question. The goal is to change the background color of an option to yellow if the user selects the correct answer, and to red if they choose incorrectly ...

Cannot execute loop

I'm currently working on creating a loop within my component that involves making server calls: getBeds() { this.patientService.getBeds(this.selectedWard).subscribe( result => { console.log(result); this.beds = result; this.getBedDet ...

Angular 2 Return {responseBody: "assigned variable with [object Object]"}

In my Angular 2 application, I am encountering an issue where I am sending a variable from a service to a component. In the template, the variable appears as expected, however, when attempting to send this variable to a PHP script using POST, I receive [ ...

Unable to retrieve nested objects from HTTP Response

After receiving data from a HTTP Response, I am trying to access and display it in my template. However, despite storing the data into a component variable, I am encountering issues when trying to access specific properties of the object. { "files": [ ], ...

What is the best way to handle closing popups that have opened during an error redirection

In my interceptor, I have a mechanism for redirecting the page in case of an error. The issue arises when there are popups already open, as they will not automatically close and the error page ends up appearing behind them. Here's the code snippet re ...

Differentiating between model types and parameters in Prisma can greatly enhance your understanding of

Consider the following scenario: const modifyData = async(data, settings) => { await data.update(settings) } In this case, the data refers to any data source, and the settings consist of objects like where and options for updating the data. How can ...

Creating a different type by utilizing an existing type for re-use

Can you help me specify that type B in the code sample below should comprise of elements from interface A? The key "id" is mandatory, while both "key" and "value" are optional. interface A { id: string; key: string; value: string | number; } /** ...

Transforming named functions in const or class constructors with Eslint and Typescript: a guide

Lately, I've been relying heavily on the code snippet from an answer that I requested: function sameValuesAsKeys<K extends string>(...values: K[]): {readonly [P in K]: P} { const ret = {} as {[P in K]: P} values.forEach(k => ret[k] = k); ...

Neither Output nor EventEmitter are transmitting data

I am struggling to pass data from my child component to my parent component using the Output() and EventEmitter methods. Despite the fact that the emitter function in the child component is being called, it seems like no data is actually being sent through ...

Tips for remembering to reactivate the Protractor Angular synchronization feature

Our test codebase is quite large, with around 10,000 lines of JavaScript code. In certain situations, we find it necessary to disable Protractor-to-Angular synchronization using the following line of code: browser.ignoreSynchronization = true; However, o ...

Angular Project: Exploring Classes and Interfaces with and without the Export Keyword

Currently, I am delving into the world of Angular. I have taken up a video course and also referred to a PDF book, but I find myself perplexed when it comes to understanding the usage of the "export" keyword... The PDF course focuses on Angular 5 and util ...

What could be the root of this next.js build issue occurring on the Vercel platform?

I recently upgraded my next.js project to version 12.0.7, along with Typescript (4.5.4) and pdfjs-dist (2.11.228), among other libraries. Locally, everything runs smoothly with the commands yarn dev for development and yarn build for building. However, af ...

Determining the Type<> of a component based on a string in Angular 2

Can you retrieve the type of a component (Type<T>) based on a string value? For example: let typeStr: string = 'MyComponent'; let type: any = getTypeFromName(typeStr); // actual type ...

Learn how to mock asynchronous calls in JavaScript unit testing using Jest

I recently transitioned from Java to TypeScript and am trying to find the equivalent of java junit(Mockito) in TypeScript. In junit, we can define the behavior of dependencies and return responses based on test case demands. Is there a similar way to do t ...

An error occurred while trying to load the configuration "next/core-web-vitals" for extension

If you're embarking on a new project using NextJs and TypeScript, chances are you may encounter the following error: Failed to load config "next/core-web-vitals" to extend from. Wondering how to resolve this issue? ...