Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why angular elements are swallowing error?

I have the simplest possible angular element within an angular project. I throw error in component belonging to angular element as follows:

dashboard-tile.component.ts user as <dashboard-tile a="100" b="50" c="25"></dashboard-tile> in index.html

ngOnInit() {
    throw "this is an error";
  }

But I see no error in chrome console. Can someone pls advice?

Link to video. Link to github repo containg the code.

Edit:

Testing:

  1. I have tested it in chrome and firefox. Its reproducible in both.
  2. If I treat above component like normal component (having <app-dashboard-tile><app-dashboard-tile/> in app.component.ts), exceptions are shown in console

A note:

  1. This question is about angular elements and not about regular angular project. Its easy to overlook this.

  2. It would be great if you could clone the project and run it locally. It wont take more that 2mins.

like image 590
dasfdsa Avatar asked Dec 17 '22 18:12

dasfdsa


2 Answers

I was able to recreate the issue you were seeing and seems to only happen when throwing error when using createCustomElement() from '@angular/elements'.

In the repo you are loading the <dashboard-tile> in the index.html file. This is loading the element outside the <app-root> and therefore suppressing the throw new Errors("error").

I believe the ngOnInit() is not function property because the DOM is loading the <dashboard-tile> element before Angular is registering.

If you load the element <dashboard-tile a="100" b="50" c="25"></dashboard-tile> in the app.component.html you should see the Errors.

See PR and Repo: Link


If you need to call it in the index.html would recommend the following:

  1. Try using console.error("error")
  2. Implement ErrorHandler (@angular/core)

    • [API Reference][0]
    • Helpful Article by Aleix Suau

Updated dashboard-tile.component.ts:

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

@Component({
  selector: 'app-dashboard-tile',
  templateUrl: './dashboard-tile.component.html',
  styleUrls: ['./dashboard-tile.component.scss']
})
export class DashboardTileComponent implements OnInit, ErrorHandler {

  @Input() a: number;
  @Input() b: number;
  @Input() c: number;

  constructor() { }

  ngOnInit() {
    debugger;
    this.handleError(new Error('This is Angular Element Error'));
  }

  handleError(err: any): void {
    console.error(err);
  }

}
like image 50
codedawi Avatar answered Dec 28 '22 11:12

codedawi


In my case Angular was swallowing the exceptions because I was calling the createCustomElement() from '@angular/elements' in the constructor of the AppModule. Moving it into the ngDoBootstrap() method did the job in my case.

So the working AppModule looks like:

export class AppModule implements DoBootstrap {
  constructor(private injector: Injector) {}

  ngDoBootstrap(): void {
    const webComponent = createCustomElement(OrderFormComponent, { injector: this.injector })
    customElements.define('my-web-component', webComponent)
  }
}
like image 25
Federico Bellini Avatar answered Dec 28 '22 11:12

Federico Bellini