I'm trying to build an example application to test Angular Ivy in combination with Angular Elements, but i can't find any information on how DI should be configured in that setting - since app.module is bypassed.
main.ts:
import { ɵrenderComponent as renderComponent } from '@angular/core';
import { AppComponent } from './app/app.component';
renderComponent(AppComponent);
app.module.ts: this is not used by main.ts, so where should HttpClientModule be loaded and custom elements be defined?
import { NgModule, Injector } from '@angular/core';
import { HttpClientModule } from '@angular/common/http/http';
import { createCustomElement } from '@angular/elements';
import { AppComponent } from 'src/app/app.component';
@NgModule({
declarations: [ AppComponent ],
imports: [ HttpClientModule ],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector) { }
ngDoBootstrap() {
customElements.define('app-component',
createCustomElement(AppComponent, { injector: this.injector }));
}
}
app.component.ts:
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.ShadowDom,
})
export class AppComponent {
constructor(private http: HttpClient) {
http.get<any>('someurl').subscribe(data => console.log(data));
}
}
This results in the following exception:
Error: Injector: NOT_FOUND [HttpClient]
I've read some hints about a 'deps' property for @Component, but it's not found (~8.0.0-beta.8). I tried adding providers: [ { provide: HttpClient } ]
to @Component, which throws
Error: Injector: NOT_FOUND [HttpHandler]
providers: [ { provide: HttpClient, deps: [HttpHandler] } ]
still throws the same exception.
Where should i configure dependencies when using Ivy? And while at it, where should createCustomElement
be called?
I added a github repository with a minimal, complete and verifiable example: https://github.com/markusdresch/ng-ivy-custom-element
EDIT Alright, i got a little further. HttpHandler has to be provided more explicitly (this is in @Component):
providers: [
{ provide: HttpClient, deps: [ HttpHandler ] },
{ provide: HttpHandler, useValue: new HttpXhrBackend({ build: () => new XMLHttpRequest() }) },
// ...
]
This way the above errors are gone and it works. However, i'm still not sure how to register the custom element.
Before you can use HttpClient , you need to import the Angular HttpClientModule . Most apps do so in the root AppModule . You can then inject the HttpClient service as a dependency of an application class, as shown in the following ConfigService example.
AJAX enables the communication with the backend / servers without refreshing the page. As AngularJS also used for single page applications. it provides built in support for AJAX communication with server. Create a service where we will create function send http requests to the server.
To answer my own question: It's possible to fire up the root injector in main.ts. It's not that straight forward as @NgModule, because dependencies have to be provided as well:
in main.ts:
const injector: Injector = Injector.create({
name: 'root',
providers: [
{ provide: HttpClient, deps: [ HttpHandler ] },
{ provide: HttpHandler, useValue: new HttpXhrBackend({ build: () => new XMLHttpRequest() }) },
]
});
renderComponent(AppComponent, { injector: injector });
I haven't really solved creating a custom element like this though, with the exception of this hack:
class AppComponentCustomElement extends HTMLElement {
constructor() {
super();
renderComponent(AppComponent, { injector: injector });
}
}
customElements.define('ng-ivy-custom-element', AppComponentCustomElement);
But this way @Inputs etc have to be routed through manually. I'll keep tinkering and update if i find something more usable.
UPDATE: according to https://juristr.com/blog/2019/05/Angular-8-and-the-Future-NGConf-2019-Roundup/#not-every-app-is-a-spa my attempt is not considered a hack, but the right way to achieve this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With