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

Is it possible to use takeUntil() with an Observable of type void?

The information provided states that the takeUntil function will continue emitting values until the passed observable emits a value, rather than until subscribe is called. I am curious about whether the following approach is considered safe: const x = ne ...

Problem with Angular Material Sidenav Styling

Currently, I am working with the mat-sideNav route and encountered a CSS issue with the sidenav after selecting a new route. When I click on a new route using the sidenav module and then return to the sidenav to change routes again, I notice that the hover ...

"Customize your Angular application by updating the background with a specified URL

Hello there, I've been attempting to modify the background URL once a button is clicked. In my CSS, I have the following default style set up. .whole-container { background: linear-gradient( rgba(0, 0, 0, 2.5), ...

Angular: Issue with subscribed variable visibility on screen

I am currently developing user management functionality. When a button is clicked, the goal is to save a new user and display an incoming password stored in the system. Below is a snippet of my code: onClick() { /*Code to populate the newUser variable from ...

The electron application along with node.js and ng framework is having issues with the file path. It seems that the g.ps1 file cannot be loaded due to

Currently, I am attempting to compile a project using Windows 10 in Visual Studio Code, and my settings are as follows: 1) npm version 6.12 2) Node.js version 12.13 3) Angular CLI: 8.3.19 The issue arises when I try to execute ng serve, resulting in th ...

Expanding Arrays in TypeScript for a particular type

There is a method to extend arrays for any type: declare global { interface Array<T> { remove(elem: T): Array<T>; } } if (!Array.prototype.remove) { Array.prototype.remove = function<T>(this: T[], elem: T): T[] { return thi ...

Angular observable goes unnoticed

I'm venturing into creating my own observable for the first time, and I'm running into issues. The data is visible in the console, but it doesn't show up when the component loads. Can anyone help me troubleshoot this problem? Here's a ...

Is it possible to execute an HTTP request using a functional resolver?

Previously, I used a class-based resolver where I could inject HttpClient in the constructor. However, this approach has now been deprecated - see the source for more information. Now, I am looking to implement an HTTP get request in a functional resolver ...

Issue with rendering object in Three.js ply loader

Just starting out with three.js and Angular 13, using three.js v0.137.0. I'm attempting to load and preview a ply file from a data URL, but all I see after rendering is a bunch of lines, as shown in this screenshot - how the ply file renders. The .pl ...

What steps can I take to ensure my CSS selector for the element is functioning properly?

Here is an example of some code: <html> <head> <style> .test{ background-color: red; p { background-color: yellow; } } </style> </head> <body> <div class="test"> ...

You cannot directly access an array useState by index in React js, but you can use the map function to

export interface JobListing { id: number, isTraded: boolean, feedback: string, title: string, message: string, skills: string[], sender: string, ipAddress: string } const GroupList = () => { const [jobListings, setJobListings] = useSt ...

Empty initial value for first item in array using React hooks

My goal is to store an array that I retrieve from an API in a useState hook, but the first entry in my array always ends up empty. The initial array looks like this: (3) ["", "5ea5d29230778c1cd47e02dd", "5ea5d2f430778c1cd47e02de"] The actual data I recei ...

What is causing the malfunction in this overloaded function signature?

Encountering an issue when attempting to declare an overloading function type with a full type signature in TypeScript. For example: // Full type signatures for functions type CreateElement = { (tag : 'a') : HTMLAnchorElement, (tag ...

Error in Prisma: Unable to retrieve data due to undefined properties (attempting to access 'findMany')

Recently, I've been working on a dashboard app using Prisma, Next.js, and supabase. Encountering an issue with the EventChart model in schema.prisma, I decided to create a new model called EventAreaChart. However, after migrating and attempting to ex ...

How can elements be collapsed into an array using the Reactive approach?

Consider this TypeScript/Angular 2 code snippet: query(): Rx.Observable<any> { return Observable.create((o) => { var refinedPosts = new Array<RefinedPost>(); const observable = this.server.get('http://localhost/ra ...

I am looking to develop a unique event that can be triggered by any component and listened to by any other component within my Angular 7 application

Looking to create a unique event that can be triggered from any component and listened to by any other component within my Angular 7 app. Imagine having one component with a button that, when clicked, triggers the custom event along with some data. Then, ...

Issue with IntelliJ: TypeScript Reference Paths Are Not Relative

I am currently using IntelliJ as my IDE, but I am facing an issue with configuring gulp-typescript to compile my typescript code. The problem arises from the fact that IntelliJ does not treat my reference paths relatively, instead it references them from m ...

Issues with integrating Angular Cypress Component tests with Tailwindcss are causing problems

While implementing Tailwindcss in an Nx style monorepo structure with 'apps' and 'libs' folders, I configured the Tailwind file as follows: content: ['./apps/**/*.{html,ts}', './libs/**/*.{html,ts}'], However, despi ...

"I'm looking for a way to store and fetch TypeScript objects with PouchDB. Any suggestions on

As someone who is new to typescript and web development, I am eager to incorporate PouchDB into my typescript project to store my objects. Despite the lack of documentation, I am struggling to find the correct approach. I have created typescript objects t ...

What strategies prove most successful in resetting a reactive angular form effectively?

I'm currently working with Reactive Forms using Angular Material inputs (mdInput) that are initialized with FormBuilder in the following way: contactForm: FormGroup; this.contactForm = this.fb.group({ name: ['', [Validators.required, Val ...