1

Well I've been stumped on this for a couple days already and I'm lost. Sometimes trying to do everything as a component doesn't work out, so I need directives.

The issue I'm facing is that when I try to export a Directive to be used in my frontend app which uses the exported Angular Elements project, components work but directives don't, making the code crash like this:

elements.js:1 TypeError: Cannot read property 'type' of null
    at new So (elements.js:1)
    at xo.resolveComponentFactory (elements.js:1)
    at elements.js:1
    at Tu (elements.js:1)
    at new t (elements.js:1)
    at Object.t.ɵfac [as factory] (elements.js:1)
    at Ps.hydrate (elements.js:1)
    at Ps.get (elements.js:1)
    at elements.js:1
    at Set.forEach (<anonymous>)

Or

elements.js:formatted:8942 TypeError: Cannot read property 'type' of null
    at new vs (elements.js:formatted:6305)
    at ms.resolveComponentFactory (elements.js:formatted:6284)
    at elements.js:formatted:8836
    at customElements.define.injector (elements.js:formatted:8837)
    at new e (elements.js:formatted:8917)
    at Object.e.ɵfac [as factory] (elements.js:formatted:8924)
    at fr.hydrate (elements.js:formatted:5139)
    at fr.get (elements.js:formatted:5008)
    at elements.js:formatted:5048
    at Set.forEach (<anonymous>)

Such line is this one:

enter image description here

For some reason, t is null. This only happens with Directives. Components work well, but the issue I have is that the Angular team does not want to give us a way to remove the component host element so I'm stuck with a DOM container tag that I don't want and it doesn't play well with some CSS frameworks in the way I want to use them. I've tried to remove the host element and move the child elements up the DOM to the host component's parent, but then two-way databinding doesn't work.

To give some context, I'd like to create an Angular directive that can work like this:

<div class="form-floating mb-3">
  <input type="email" my-directive-here class="form-control" id="floatingInput">
  <label for="floatingInput">Email address</label>
</div>

That way I can add extra functionality to my input tag with my-directive-here which I'm exporting as:

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

@Directive({
  selector: '[MyDirectiveHere]'
})
export class TestDirective {

  constructor() { }

}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { FormsModule } from '@angular/forms';
import { TestDirective } from './test.directive';

@NgModule({
  declarations: [TestDirective],
  imports: [
    FormsModule,
    BrowserModule
  ],
  entryComponents: [TestDirective]
})
export class AppModule {
  constructor(private injector: Injector) {
    customElements.define('MyDirectiveHere', createCustomElement(TestDirective, { injector: this.injector }));
  }
  ngDoBootstrap() { }
}

Pretty simple but it crashes. Any ideas welcome!

DARKGuy
  • 843
  • 1
  • 12
  • 34
  • 1
    As far as I can tell, logically, directives cannot work outside of Angular. The Angular template compiler is the one responsible for attaching directives to elements/components, and the html outside of the element is not generated by Angular. – Aviad P. Jul 26 '21 at 06:10
  • 1
    ... and also there is no way to dynamically create and attach an Angular directive to an element. – Aviad P. Jul 26 '21 at 06:59

0 Answers0