0

I have created an Angular Custom Element (Web Component) which calls functions in an Angular service. This all works fine when imported into AngularJS.

Is it possible to call functions in the Angular Custom Element service directly from the AngularJS app?

This is the Custom Element controller:

import { Component, Input, OnInit } from '@angular/core';
import { FeedbackService } from './feedback.service';

@Component({
  selector: 'app-feedback-ce',
  templateUrl: './feedback.component.html',
  styleUrls: ['./feedback.component.scss'],
})

export class FeedbackComponent implements OnInit {

  constructor(private feedbackService: FeedbackService) { }

  ngOnInit() {
  }

  onCallService(event) {
    this.feedbackService.callService();
  }

}

This is the service:

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

@Injectable({
  providedIn: 'root'
})
export class FeedbackService {

  constructor() { }

  callService() {
    console.log('user feedback service called!!');
  }
}

The template:

<h2><b>This is an Angular Custom Element (Web Component)!!!!</b></h2>
  <a (click)="onCallService()" href type="button">Call Test Service.</a>
</p>

This is the main app.component.ts:

import {Injector, NgModule} from '@angular/core';
import {createCustomElement} from '@angular/elements';
import {BrowserModule} from '@angular/platform-browser';
import {FeedbackComponent} from './angular/main/dashboard/dashboard-panel/panels/feedback/feedback.component';

@NgModule({
  declarations: [
    FeedbackComponent,
  ],
  imports: [
    BrowserModule,
  ],
  entryComponents: [FeedbackComponent],
  providers: []
})
export class AppModule {
  constructor(private injector: Injector) {
  }

  ngDoBootstrap() {
    const customElement = createCustomElement(FeedbackComponent, {injector: this.injector});
    customElements.define('app-feedback-ce', customElement);
  }
}

This is then built and the resulting .js files imported into the AngularJS app in index.html.

The Custom Element can then be used in AngularJS:

<app-feedback-ce></app-feedback-ce>

All works fine.

But is there a way to call callService() directly from elsewhere within the AngularJS app?

UPDATE

Hi

Managed to get this working but not sure if it is good practice!

AngularJS should not really access the DOM directly via a controller.

This is the custom element where the function is defined as an input which then call the service:

import { Component, Input, OnInit } from '@angular/core';
import { FeedbackService } from './feedback.service';

@Component({
  selector: 'app-feedback-ce',
  templateUrl: './feedback.component.html',
  styleUrls: ['./feedback.component.scss'],
})

export class FeedbackComponent {
  @Input()
  get showUserFeedBack() {
    return this.feedbackService.showUserFeedBack();
  }

  constructor(private feedbackService: FeedbackService) { }

  onShowFeedbackFormClick() {
    this.feedbackService.showUserFeedBack();
  }

}

This is how it is called in the AngularJS app from a controller:

 onUserFeedbackClick() {
    const feedbackCustomComponent = angular.element('app-feedback-ce');
    if (!feedbackCustomComponent) {
      return false;
    }

    return feedbackCustomComponent[0].showUserFeedBack;
}

Any thoughts about this and is there a better way?

random
  • 41
  • 2
  • I think you can achieve it by adding an input into your WebComponent that calls the service by checking the input changes with the ngOnChanges function. Doing it, so, with javascript you can call this attribute (the @input wich will be available on your compiled webcomponent) and the service will be called. – Ricardo Machado Jul 29 '22 at 05:52
  • Did you get chance to check [Call Angular web component method](https://stackoverflow.com/a/62959606/2435473)? – Pankaj Parkar Jul 29 '22 at 06:18
  • Hi Guys - Managed to get this working but now sure it is good practice to access the DOM directly from a controller. I have posted an update above. – random Aug 03 '22 at 00:41

0 Answers0