Why angular elements are swallowing error?
Asked Answered
P

2

5

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.

Platt answered 10/3, 2019 at 20:42 Comment(4)
hi the snippet / video / repo all have different code, so its hard to tell what you are working on. anyway a clean project with only the exception works ok. did you try in another browser just to verify?Chile
maybe you can try this: #18655854Chile
@Chile I have linked my component file. Can you see my edit. Thanks.Platt
Its a bug. I have logged a github issue for this: github.com/angular/angular/issues/29211Platt
A
10

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)

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);
  }

}
Anabel answered 10/3, 2019 at 21:24 Comment(11)
Can I ask how did you try to recreate the issue? Did you clone my project or create a webcomponent yourself?Platt
I just created a simple web component on slackbiltz. I did check out the repo thoughAnabel
can you give me the link of that stackblitz?Platt
Also pls see my edit. If i treat it like a normal component, errors are shown in console as expected.Platt
Your project is a regular angular project and not angular-element. Can you clarify?Platt
Oh my apologizes, my oversight. It is just a normal angular project. I am going to try using your repo.Anabel
Haha. I have asked couple of other angular-element qustion on SO. Almost 100% of people answer it, thinking of it like normal angular project. Not a problem :) . I will make sure to add a note at the bottom.Platt
Looks ok like this.Chile
@Chile thank you point me in the right direction with showAsComponent(). I went back and updated my comment. I looks like the element was not beginning loaded by Angular and being referenced in the index.html.Anabel
Thanks. Loading it into app.component worked. I will look into it tomorrow.Platt
I think we all learned a lot from "2 minutes" of angular elements:) good luckChile
V
4

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)
  }
}
Ventricle answered 7/10, 2020 at 9:42 Comment(1)
This should have more visibility, and probably the angular documentation should be updated too since their example puts the createElement in the constructor too. It seems pretty useless to me to put this in the constructor as it seems to hide or not report errors correctly when it's there.Stenotype

© 2022 - 2024 — McMap. All rights reserved.