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

Unlocking the Secrets of AnimatedInterpolation Values

I have a question about how to access the value of an AnimatedInterpolation in react-native without resorting to calling private code. To achieve this, I first create an animated value and then wrap it in an interpolation like so: animated = new Anima ...

Unleashing the power of RXJS: Leveraging IntervalObservable coupled with the

I recently incorporated HTTP pooling into my Angular application using IntervalObservable and startWith for immediate activation. I'm curious to know if IntervalObservable waits for the initial/previous call to finish streaming data. Also, is there a ...

Upon loading a website, the Chrome browser will automatically set the zoom level to 80%

Recently, I've encountered a perplexing issue with Chrome where my website is automatically zoomed out from 100% to 80%. It seems that browsers cache zoom settings based on the domain and apply them when users revisit the site. However, in this case, ...

What are the steps to set up NextJS 12.2 with SWC, Jest, Eslint, and Typescript for optimal configuration?

Having trouble resolving an error with Next/Babel in Jest files while using VSCode. Any suggestions on how to fix this? I am currently working with NextJS and SWC, and I have "extends": "next" set in my .eslintrc file. Error message: Parsing error - Can ...

What is causing Angular to consistently display the first object in the array on the child view, while the child .ts file correctly prints information from a different object?

Once a card of any object is clicked, the information of that specific object will be printed to the console. However, the child view will only display the details of the first object in the array it retrieves from. All pages are included below. A visual e ...

Navigating from a Card to a new View in Angular

I am currently developing a project using Angular (latest version). Within my application, I have the functionality to dynamically generate bootstrap cards from an Order Array and display them in my "Order-Item-Component through its respective template. ...

Activate the mat-menu within a child component using the parent component

Incorporating angular 6 along with angular-material, I am striving to trigger the matMenu by right-clicking in order to utilize it as a context menu. The present structure of my code is as follows. <span #contextMenuTrigger [matMenuTriggerFor]="context ...

Is CORS necessary when using npm, and is Putty a viable tool for web application development?

Currently, I am immersed in a web application project that relies on the following technologies: Express.js + Node.js MySQL Angular 4 PM2 (Process manager) Here are the libraries utilized on the backend: express body-parser jsonwebtoken bcrypt-nodejs ...

Is it better to store data individually in localStorage or combine it into one big string?

When it comes to keeping track of multiple tallies in localStorage, one question arises: Is it more efficient to store and retrieve several small data points individually or as one larger chunk? For example: localStorage.setItem('id1', tally1); ...

Exploring Angular observables: Tips for gathering specific fields from a nested array within an object into a new array

I am working on parsing a JSON object and extracting specific fields to create their own array. My goal is to loop through the provided object and gather the 'appSupportedId' values into a separate array. An issue has arisen, leading to an ERRO ...

TypeScript has encountered an issue where a specific type A cannot be assigned to another type A, even though

Encountering a Typescript issue where it claims that type A is not compatible with type A, even though they are identical: Check out this playground link for the code snippet in context: declare interface ButtonInteraction { user: any; customId: strin ...

Encountering an issue in Angular 4 AOT Compilation when trying to load a Dynamic Component: Error message states that the

My Angular application is facing challenges when loading dynamic components. Everything works smoothly with the JIT ng serve or ng build compilation. Even with AOT ng serve --prod or ng build --prod, I can still successfully build the application. Lazy loa ...

Set an enumerated data type as the key's value in an object structure

Here is an example of my custom Enum: export enum MyCustomEnum { Item1 = 'Item 1', Item2 = 'Item 2', Item3 = 'Item 3', Item4 = 'Item 4', Item5 = 'Item 5', } I am trying to define a type for the f ...

An error occurred: The property 'toUpperCase' cannot be read of an undefined Observable in an uncaught TypeError

Encountering an issue during the development of a mobile app using the ionic framework for a movie application. After finding an example on Github, I attempted to integrate certain functions and designs into my project. The problem arises with the 'S ...

Learn the process of adjusting the Time Zone in Angular2-HighCharts!

I've been struggling for a few days now trying to adjust the UTC time in an area chart using Angular2-HighCharts. The backend API is returning timestamps which I then inject into the chart, but each time it's being converted to "human time" with ...

Enforcing alias types in TypeScript arguments is necessary for maintaining consistency and clarity

I'm currently facing a challenge with type unions and aliases. I have an alias for values that can possibly be null or undefined, along with a function that handles these values. Everything is running smoothly and safely. However, there are instances ...

I'm curious if there is an eslint rule specifically designed to identify and flag any unnecessary spaces between a block comment and the function or

Can anyone help me find a solution to prevent the following issue: /** * This is a comment */ function foo() { ... } I need it to be corrected and formatted like this: /** * This is a comment */ function foo() { ... } ...

Malfunctioning designs arise when Angular-CLI deploys application with webpack

Encountering a strange issue while attempting to run my angular application using angular CLI. Executing ng serve results in the following message post-compilation : A Warning appears... (Emitted value instead of an instance of Error) Cannot find source ...

Tips for addressing the error "Ensure each child in a list has a distinctive 'key' prop" in a React function using TypeScript

Encountered the following warning: Warning: Each child in a list should have a unique "key" prop. Inspect the render method of TabContext. Refer to https://reactjs.org/link/warning-keys for more details. in TabForGroupInList (at Product.tsx:148) ...

Is it necessary to unsubscribe from an Angular HTTP-Request when using switchMap?

I have a question about managing subscriptions in my Angular application. I'm currently using the combineLatest operator to create an observable from two Angular observables, route.params and route.queryParams. This combined observable is then used as ...