Extracting event handlers using @ContentChildren: A guide

I am dealing with a my-button component that needs to be enclosed within a my-button-row component in the following manner:

<my-button-row>
    <my-button [label]="Some Label" (click)="func1($event)"></my-button>
    <my-button [label]="Some Other Label" (click)="func2($event)"></my-button>
</my-button-row>

However, when I try to access the (click) event handlers assigned to the my-button components using @ContentChildren, I run into an issue.

export class MyButtonRowComponent {
    @ContentChildren(MyButtonComponent) buttons: QueryList<MyButtonComponent>;

    ngAfterContentInit() {
        // unable to determine the (click) setting
        console.log(this.buttons); 
     }
}

The output of console.log(this.buttons) is a QueryList containing MyButtonComponents without any associated click events. How can I identify which event handlers have been set for the ContentChildren?

My intention is to individually wrap each my-button child component with a stylable div. Transforming from:

<my-button-row>
    <my-button [label]="Some Label" (click)="func1($event)"></my-button>
    <my-button [label]="Some Other Label" (click)="func2($event)"></my-button>
</my-button-row>

to this:

<my-button-row>
    <div class="styleme">
        <my-button [label]="Some Label" (click)="func1($event)"></my-button> 
    </div>
    <div class="styleme">
        <my-button [label]="Some Other Label" (click)="func2($event)"></my-button>
    </div>
</my-button-row>

Existing solutions for generating dynamic components are not appropriate as they create new components which lead to the loss of (click)="func1($event)".

Answer №1

When it comes to wrapping tags with other tags in Angular, it is advised not to manipulate the DOM directly as it is considered a bad practice. Instead, you should create a wrapper component that will handle this task for you.

An example of how to achieve this can be seen here: Stackblitz

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-surrounder',
  template: `
<div class="styleme">
    <ng-content></ng-content>
</div>
`,
  styleUrls: ['./surrounder.component.css']
})
export class SurrounderComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Answer №2

It would be more efficient to define the style within the my-button component directly. If you require varying styles for different occurrences of my-button, consider passing an @Input with the designated style id for each specific instance of the component.

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

The Angular language service is experiencing difficulties in VS Code when it comes to newly created components using the CLI

I am currently facing an issue with the angular language service in an older project that already has a few components created. The problem arises when trying to generate NEW components using the CLI. For instance, a new component generated today: https:/ ...

The functionality of arguments in the whenAllDone promise/deferred javascript helper seems to fail when attempting to encapsulate existing code within a Deferred

My goal is to implement the solution provided in TypeScript from Stack Overflow: UPDATE 2 - The issue with the original answer is that it does not support a single deferred. I have made modifications to reproduce the error in his fiddle. http://jsfiddle.n ...

Encountering errors when subscribing to a BehaviorSubject in Angular 8

I am currently working on a Single Page Application using Angular 8 where I am trying to pass data from a component to a service. In the service, I am subscribing to it using rxjs BehaviorSubject. However, when I compile the code using Angular CLI, I encou ...

Custom Cypress command that provides function outputs

When I implement the following code snippet: export const test = () => ({ yo: () => console.log('test'), }); Cypress.Commands.add('test', test); declare global { namespace Cypress { interface Chainable<Subject> { ...

Having trouble with installing npm package from gitlab registry

I recently uploaded my npm package to the GitLab package registry. While the upload seemed successful, I am facing an issue trying to install the package in another project. When I run npm install, I encounter the following error: PS E:\faq\medu ...

Stop the inclusion of the scrollbar in the mat-drawer-inner-container within the Angular mat-drawer Component

Background Story: Working on designing a screen layout that includes the use of a mat-drawer to display a custom component. The challenge arises when the custom component gets nested inside a div (with class="mat-drawer-inner-container") automatically adde ...

Guide on building a Vue3 component with TypeScript, Pug Template engine, and Composition API

Whenever I try to export components within <script setup lang="ts"> and then use them in <template lang="pug">, an error is thrown stating that the component is defined but never used. Here's an example: <template la ...

Breaking down types in Typescript: Extracting individual types from an object containing multiple objects

Having a query: const queries = { light: { a... b... }, dark: { a... b... c... d... }, The react element requires a colors parameter that corresponds to one of the themes in the above object, with each theme containing a un ...

Extending a type by adding properties from separate files using TypeScript

I am faced with a situation where I have a file containing either a type or interface variable (all of which are exported), and I need to add new properties to this variable from different files without using extends. Essentially, making changes to the sam ...

Embedding a component inside another layout component in Angular

I'm attempting to insert a component into another layout component using a service, but I can't seem to get it working. Here is my current layout structure: AppComponent | AppLayoutComponent | ------------------------------------- ...

Issue with RxDB: Collection not found upon reload

Exploring the integration of RxDB in my Angular project. I wanted to start with a simple example: export const LANG = { version: 0, title: "Language Key", type: "object", properties: { key: { type: "string", primary: true } }, requ ...

Error: Unable to execute function abc, it is not defined as a function in this context

Having trouble with a fronted or JavaScript issue where it can't find the defined function in the file. I'm working on integrating Apple Pay and need to call the back-end API based on a specific event. Here is my code. ACC.payDirect = { _autoload ...

Deactivating Google Map Clustering for Individual Markers

I'm currently utilizing Angular 4, Google Maps v3, and Marker Clusterer v2 - all of which are the latest versions. I'm attempting to implement a straightforward example found in the official Google Maps documentation (https://developers.google.co ...

Building Angular CLI Applications with Separate SCSS Files for Browser Loading

Below is how I am importing the scss file: import { Component, OnInit, ViewEncapsulation } from '@angular/core'; @Component({ ...., styleUrls: ['../../scss/dashboard_admin.scss'], encapsulation: ViewEncapsulation.None }) e ...

Is there a way to merge my local store with Firestore using ngrx entity?

Currently, I'm facing a challenge while using NgRx and Firestore as I attempt to keep the local store in sync with a firestore collection. I have set up an observable that triggers when the firestore collection is updated. However, in my reducer, I am ...

My application is functioning properly, yet Angular keeps throwing an error

I created a data filtering pipeline that functions perfectly, but I am encountering an error. Why is this happening? The error message: ERROR TypeError: Cannot read property 'filter' of undefined at FilterPipe.push../src/app/filter.pipe.ts. ...

Why can't I omit <someUnion, oneInterface> in TypeScript?

Kindly review this simple example: interface A { a: number; } interface B { b: number; } interface C { c: number; } type ABC = A | B | C; type omitA = Omit<ABC, A>; https://i.sstatic.net/5Mun4.png Unfortunately, I am unable to exclude an i ...

In React-Redux, attempting to assign a value to an empty string is not permitted

When using the useDispatch hook, I am facing an issue where I cannot set the string to an empty value. Instead, it always sets the value to the last character in the string. App.tsx const dispatch = useDispatch(); dispatch(updateLocation('')); ...

Angular2 recursive template navigation

Is it possible to create a recursive template in Angular 2 without using ng-include? It's puzzling why this feature seems to be missing in Angular 2... HTML: <div ng-app="app" ng-controller='AppCtrl'> <script type="text/ng-templat ...

Help! My Angular CLI version 8.2.2 is displaying squares instead of the Font-awesome icons

I successfully added Font Awesome using the command npm install --save font-awesome angular-font-awesome from https://www.npmjs.com/package/angular-font-awesome. After linking it in my angular.json file: "styles": [ "src/styles.css", "node_modu ...