Hone logo
Hone
Problems

Building a Custom Element Wrapper in Angular

This challenge focuses on integrating custom elements (web components) into an Angular application. Custom elements offer a way to reuse components across different frameworks, and Angular provides mechanisms to effectively manage and interact with them. Your task is to create an Angular component that wraps a pre-existing custom element, providing Angular-specific functionality like data binding and event handling.

Problem Description

You are tasked with building an Angular component, my-custom-element-wrapper, that encapsulates a custom element named my-custom-element. my-custom-element is assumed to be already defined and registered in the browser (you don't need to define it; it's provided). This wrapper component should:

  1. Instantiate and Attach: Create an instance of my-custom-element within the Angular component's lifecycle.
  2. Property Binding: Allow Angular properties to be bound to attributes of the custom element. Specifically, the Angular component should have a property called name which should be reflected as the name attribute on the custom element.
  3. Event Handling: Listen for a custom event named custom-event emitted by my-custom-element. When this event is fired, the Angular component should log a message to the console containing the event's detail property.
  4. Lifecycle Management: Ensure the custom element is properly destroyed when the Angular component is destroyed to prevent memory leaks.

Expected Behavior:

  • When the Angular component is initialized, an instance of my-custom-element should be created and appended to the component's host element.
  • Changes to the name property in the Angular component should be reflected in the name attribute of the custom element.
  • When my-custom-element emits the custom-event, the Angular component should log a message to the console.
  • When the Angular component is destroyed, the custom element instance should be removed.

Examples

Example 1:

Input: Angular component with name="John Doe"
Output: A `my-custom-element` instance with the attribute `name="John Doe"` is created and attached to the Angular component's host element.  When `my-custom-element` emits `custom-event` with detail `{message: "Hello from custom element!"}`, the console logs "Event received: Hello from custom element!".
Explanation: The Angular component binds the `name` property to the custom element's `name` attribute and listens for the `custom-event`.

Example 2:

Input: Angular component with name="Jane Smith" and the custom element emits `custom-event` with detail `{message: "Goodbye!"}`.
Output: The `my-custom-element` instance's `name` attribute is updated to "Jane Smith". The console logs "Event received: Goodbye!".
Explanation: The Angular component updates the attribute and handles the event.

Example 3: (Component Destruction)

Input: The Angular component is destroyed.
Output: The `my-custom-element` instance is removed from the DOM and its resources are released.
Explanation: Proper lifecycle management prevents memory leaks.

Constraints

  • The custom element my-custom-element is already defined and registered. You do not need to define it. Assume it has a name attribute and emits a custom-event with a detail property.
  • The Angular component should be a standard Angular component, using TypeScript.
  • The solution should be compatible with a recent version of Angular (e.g., Angular 14+).
  • The solution should avoid using any type where possible.

Notes

  • Consider using Angular's lifecycle hooks (e.g., ngOnInit, ngOnDestroy) to manage the custom element's lifecycle.
  • You'll need to use the Element API to interact with the custom element.
  • Think about how to handle potential errors when creating or interacting with the custom element.
  • This problem focuses on the integration aspect; you don't need to implement the custom element itself. Focus on how Angular can effectively wrap and manage it.
  • You can use a simple div as the host element for the Angular component.
Loading editor...
typescript