dangerisgo
dangerisgo

Reputation: 1271

Angular 2 Accessing directive in TS returns undefined

I'm trying to have a dynamic component similar to the example they have here: https://angular.io/guide/dynamic-component-loader

I have to dynamically add/remove child components depending on what is selected as a 3rd party requirement. (It injects to specific elements on my page)

I followed their example to obtain the viewContainerRef from the directive but unfortunately, the directive is undefined. Here is what I have got:

items-preview.component.ts:

generateBody(items: Item[]) {

  for (const item of items) {
    const previewItem: ItemPreviewItem = new ItemPreviewItem(ItemPreviewTemplateComponent, {});

    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(previewItem.component);

    const viewContainerRef = this.itemPreviewHost.viewContainerRef;
    viewContainerRef.clear();

    const componentRef = viewContainerRef.createComponent(componentFactory);
    (<ItemPreviewTemplateComponent>componentRef.instance).data = previewItem.data;
  }
}

items-preview.directive.ts

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[k8ItemPreviewHost]',
})
export class ItemPreviewDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

And the template to be injected:

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


@Component({
  template: `
    <div class="job-ad">
      <h4>Headline goes here!</h4> 

      Body goes here!
    </div>
  `
})
export class ItemPreviewTemplateComponent {
  @Input() data: any;
}

And the parent container (snippet):

<div class="preview-body" id="learnosity-content-body" [hidden]="hideResults">
    <ng-template k8-item-preview-host></ng-template>
</div>

Pretty barebones, but I just want the basic framework so I can understand by example how things work before I modify for my application. Unfortunately, when it hits this line:

const viewContainerRef = this.itemPreviewHost.viewContainerRef;

It says 'Cannot read property 'viewContainerRef' of undefined'. I've tried using exportAs on the directive and referencing that, no go. I've tried using ViewChildren on the Directive name, that returned 0 results. I've removed the [hidden] property from the div (as I remember another post referencing *ngIf) but that didn't work. All of this happens way after the DOM is loaded (on demand when a user clicks a button). Any ideas? Thanks!

EDIT: Declared like so:

@ViewChild(ItemPreviewDirective) itemPreviewHost: ItemPreviewDirective;

Upvotes: 0

Views: 524

Answers (1)

dangerisgo
dangerisgo

Reputation: 1271

Found the solution: My directive selector was using camel case (lint warning) instead of dashed notation. So I changed it from

'[k8ItemPreviewHost]'

to

'[k8-item-preview-host]'

Upvotes: 1

Related Questions