5

Inputs can be provided to instances of an Angular Element via attributes in HTML:

<some-custom-element someArg="test value"><some-custom-element>

Or using setAttribute.

But attributes can only be strings.

Is there a way to pass non-strings, even JavaScript objects? Perhaps I can obtain the instance of the component class directly from the app using the custom element?

Alexander Taylor
  • 16,574
  • 14
  • 62
  • 83

1 Answers1

3

Note that setAttribute only takes strings since attributes are strings, but DOM elements can have non-string properties. See also: What is the difference between properties and attributes in HTML?

Inspect the custom element and notice that it actually is a combination of HTMLElement (NgElement more specifically) and your component class:

console.dir(document.querySelector('some-custom-element'));

So, as soon as you locate the DOM element, you already directly have the instance of your component! Then you can directly access the object and set properties on it like this:

import {FooElement} from '...';

const myElement = document.querySelector('some-custom-element')! as HTMLElement & FooElement;

// Number instead of string!
myElement.foo = 5;

That would work with this example Angular Element:

@Component({
  ...
})
export class FooElement {
  @Input() foo = 0;
}

At least this works with the component's properties. I haven't tested if methods are also exposed and I'm not sure how EventEmitters work in Elements.

Alexander Taylor
  • 16,574
  • 14
  • 62
  • 83
  • Hello, thank you so much for this Q&A! Do you know if everything here is still true nowadays? Also is this documented somewhere? Can I rely on this or may this change without notice? Also, can you please expand your answer adding info on methods and EventEmitters? – Pedro A May 02 '22 at 23:14
  • I've just figured out that if I use my custom element that was made in Angular within another app also made in Angular, it just works automagically. Something like `[someObject]="foo"` works, it just works. Amazing. – Pedro A May 04 '22 at 00:49