Encountering difficulty retrieving host component within a directive while working with Angular 12

After upgrading our project from Angular 8 to Angular 12, I've been facing an issue with accessing the host component reference in the directive.

Here is the original Angular 8 directive code:

export class CardNumberMaskingDirective implements OnInit {

  unmaskedValue: string;

  constructor(private control: NgControl,
              private element: ElementRef,
              private _viewContainerRef: ViewContainerRef) {}

  ngOnInit() {
    this.hide(this.element.nativeElement);
  }

  @HostListener('focusout', ['$event.target'])
  hide(input) {
    const host = this._viewContainerRef['_view'].component;
    if (host['disableMask'] instanceof Function) {
      host['disableMask'](this.control.name);
      setTimeout(() => {
        this.unmaskedValue = input.value;
        const value = input.value.replace(/\s/g, '');
        if (value.length > MASKED_LENGTH) {
          const formatted = input.value.replace(MASKING_REGEXP, '●●●● ●●●● ●●●● ');
          this.control.valueAccessor.writeValue(formatted);
        }
      }, 0);
    }
  }

  @HostListener('focusin', ['$event.target'])
  show(input) {
    const host = this._viewContainerRef['_view'].component;
    const value = input.value.replace(/\s/g, '');
    if (value.length > MASKED_LENGTH) {
      this.control.valueAccessor.writeValue(this.unmaskedValue);
    }
    if (host['enableMask'] instanceof Function) {
      host['enableMask'](this.control.name);
    }
  }

}

In Angular V12, the usage of _view has changed to _hostLView for accessing the component reference. However, even after using

this._viewContainerRef['_hostLView '].component;
, I'm still unable to get the component reference.

I came across a similar question on Stack Overflow and tried the solution provided here, but unfortunately, it didn't work for me as I wasn't able to retrieve the component references. Any suggestions would be greatly appreciated.

Answer №1

There is no one-size-fits-all solution, an alternative approach is to utilize the standard InjectionToken:

export interface IComponent {}

export const token: InjectionToken<IComponent> = new InjectionToken<IComponent>('IComponent');

@Component({
providers: [{provide: token, useExisting: forwardRef(() => MyComponent1)}]
})
export class MyComponent1 implements IComponent {}

@Component({
providers: [{provide: token, useExisting: forwardRef(() => MyComponent2)}]
})
export class MyComponent2 implements IComponent {}

@Directive({})
export class MyDirective {
    constructor(@Inject(token) component: IComponent){}
}

To add more rigidity, you can incorporate @Host() and/or @Self().

Answer №2

To utilize your host component within a directive, you can leverage Dependency Injection (DI).

For instance:

constructor(
 @Self() private readonly module: HostModule
) {}

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

Error: Typescript foreach loop encountering 'Expression yields void type'

Currently, I am working on setting up a cron job to monitor the completion of my tournaments and trigger some specific code upon completion. For reference, I came across this example: During deployment of my code, an error popped up as follows: ERROR: fu ...

Return a potential undefined output

I am working with a variable called root which could potentially be undefined. Its value is only determined at runtime. const root = resolvedRoot || await this.fileSystem.getCurrentUserHome(); console.log('root.uri = ' + root.uri); The existenc ...

Tips for efficiently utilizing Hooks with React Context:

I am currently working on my application and utilizing React Context with the setState function. const userContext = React.createContext([{ user: {} }, () => {}]); const userHook = useState({ user: {} }); <userContext.Provider value={userHook}> / ...

What is the most effective way to receive all values sent to an Observer upon a new subscription?

I have an observer that receives various values emitted to it at different times. For instance sub = new Subject<any>(); sub.next(1); sub.next(2); sub.next(3); #hack 1 sub.next(4); sub.next(5); sub.next(6); #hack 2 If there is a ...

The date format being sent by Angular to Java is incorrect, resulting in the inability to create an object in the

In my coupon system, I am experiencing an issue with the date format. The Java coupon bean has a date.sql startDate and endDate, while the Angular coupon model includes startDate:Date and endDate:Date in its constructor. However, when I display the dates o ...

Data retrieval from DynamoDB DocumentClient does not occur following a put operation

I am currently working on testing a lambda function using the serverless framework in conjunction with the sls offline command. The purpose of this lambda is to connect to my local DynamoDB, which has been initialized with a docker-compose image, and inser ...

Encountered difficulties when attempting to install Angular Universal in my angular13 application

I'm facing some challenges while trying to incorporate @nguniversal/ into my angular 13 application. Are there any experts who can offer assistance? Angular CLI: 13.0.4 Node: 16.13.1 Package Manager: npm 8.1.2 npm ERR! code ERESOLVE npm ERR! ERESO ...

Condition for rendering child components using Angular guard

I am faced with a scenario where I have 3 children in a parent component and I need to render them based on specific conditions: If my variable is equal to zero, the welcomePage should be rendered If the variable falls between one and ten, then the interm ...

By default, the ejs-datetimepicker in @syncfusion/ej2-angular-calendars will have an empty input field

I incorporated a datetime picker from @syncfusion/ej2-angular-calendars into my project. However, I noticed that the datetime picker displays the current date and time by default in its input field. Instead, I would like the input field to be empty when ...

Directive for displaying multiple rows in an Angular table using material design

I am attempting to create a dynamic datatable with expandable rows using mat-table from the material angular 2 framework. Each row has the capability of containing subrows. The data for my rows is structured as an object that may also include other sub-ob ...

Encountering errors while working with React props in typing

In my application, I am utilizing ANT Design and React with 2 components in the mix: //PARENT const Test = () => { const [state, setState] = useState([]); function onChange( pagination: TablePaginationConfig, filters: Record<string, ...

The Error message "Property 'data' is not present in Type <void> | AxiosHttpResponse<any>" is indicating that the data property is missing on

When I fetch data for a specific user, I have a promise that I use to setState. Below is the implementation: getUserUsername = (): string => { const { match } = this.props; return match.params.username; }; onFetchUser = () => getUse ...

Using React components within an Angular 6 application: A comprehensive guide

Looking for advice on how to reuse React components in an Angular 6 application. Can anyone recommend the best approach for accomplishing this? ...

What is the best way to reorganize an object's properties?

Looking for a way to rearrange the properties of an existing object? Here's an example: user = { 'a': 0, 'b': 1, 'c': 3, 'd': 4 } In this case, we want to rearrange it to look like this: user = { &a ...

A guide on implementing react-pose alongside @reach/router in a React Typescript project

I'm facing a challenge in my React app as I attempt to convert a JS example using react-pose and @reach/router to TypeScript, but unfortunately, it's not functioning properly. Below are the relevant typings from react-pose: import { ComponentTy ...

Creating columns on the fly within a row

I would like to create a layout where images are displayed in one row, but if the screen size changes, I don't want them to wrap and display below. Instead, I want to show a button that redirects to another page. I'm not sure how to achieve this. ...

"Setting Up a Service in Angular: A Step-by-Step Guide

I am facing an issue with a root service that contains composition within it, as shown below: import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class MapService { private rmap: RMap; ini ...

Using ngFor to iterate over a list of items in Angular and displaying them conditionally using ng

In the process of creating a template, I am faced with this challenge: <ul> <li *ngFor='let link of links'> <ng-container *ngIf="link.type == 'complex'; then complexLink else simpleLink"></ng-container& ...

Measuring Feedback: Utilizing Angular 4 to calculate review ratings

I'm facing a challenge while working on a review form using Firebase and Angular 4. The issue is with calculating the total length of added reviews and the sum of their ratings. Each time a new review is submitted, it gets pushed to a list of objects ...

Using Typescript to resolve a package from a location other than the default node_modules directory

I am currently delving into typescript and eager to start dabbling in creating packages. Here is the current layout of my project: myProject/ ├── node_modules/ ├── src/ │ ├── app │ ├── index.ts │ ├── packages ...