Angular Elements - pass a complicated input to my web component
Asked Answered
F

2

13

I started lately to play a little bit with angular elements that was released in angular V6, I opened a small sandbox project for that purpose. https://github.com/Slash7GNR/ndv-angular-elements Now I've tried to add a more complicated input to my web component - I've tried to add an array input as follows: in app.component.ts I've added:

@Input() welcomeMessages: string[];

and in the template I've added:

<div *ngFor="let message of welcomeMessages; let index = index">
    {{index}} - {{message}}
</div>

Then, I've created a static html file and added the following code: (pls-wrk is a web component generated by angular elements feature)

<pls-wrk></pls-wrk>
<script>
let arr = [“wow”,”wow2"];
let elementByTag = document.getElementsByTagName(‘pls-wrk’)[0];
elementByTag.setAttribute(“welcome-messages”, arr);
</script>
<script src="ndv-elements.js"></script>

I’m getting the following error:

Uncaught Error: Cannot find a differ supporting object ‘wow,wow2’ of type ‘string’. NgFor only supports binding to Iterables such as Arrays.

I've tried as well to bind an array via the element itself like this:

<pls-wrk welcome-messages=”[‘wow’,wow2']”></pls-wrk>

But neither this worked.

I've tried as well to bind an input which is an object, but I couldn't see the result in the html.

Anyone here who could successfully pass an array / an object as an input to an angular element?

Faceplate answered 11/6, 2018 at 8:9 Comment(0)
F
24

So I found the answer, I had two main problems:

  1. I had to add the angular elements script (ndv-elements.js) before initializing the attributes.
  2. The thing with HTML attribute, is that they are all passed as strings, in contrast to angular or other framework where you can pass objects / arrays, so when using setAttribute method, the attribute is being initialized as a string which causes a problem with inputs that are objects / arrays, the solution is to set the attribute as follows: elementByTag.welcomeMessages = array;

So the full solution will be:

<pls-wrk>
</pls-wrk>
<script src="ndv-elements.js"></script>
<script>
let arr = ['a1','a2','a3'];
let wrk = document.querySelector('pls-wrk');
wrk.welcomeMessages = arr;
</script>

References:

https://github.com/angular/angular/issues/24415

https://medium.com/@gilfink/using-complex-objects-arrays-as-props-in-stencil-components-f2d54b093e85

Faceplate answered 12/6, 2018 at 9:15 Comment(1)
Yes, it might also happen when you are running "ng serve" the app scripts (including angular elements dependencies) are added to the body so if your script setting the property is before that, it wont work.Parody
Z
2

You can pass the complicated type as an inline attribute by doing this, declare your Input() directive using Setter/Getter.

internalSelectedItem: any;

@Input()
  get selectedItem(): any { return this.internalSelectedItem; }
  set selectedItem(item: any) {
    if (typeof item == "string")
      this.internalSelectedItem = JSON.parse(item);
    else
      this.internalSelectedItem = item;
  }

And now, you can pass Array directly from the angular element tag.

<custom-element selected-item="[458, 470, 476]">  </custom-element>

Or from script

var arr =  [458, 470, 476]
customElem.selectedItem = arr;

Please note!

You may need to check the type of value you are passing and take action accordingly, as I'm doing in my scenario.

As per my understanding, when you pass inline as attribute's value, the element takes it as string type.

Zebapda answered 22/5, 2021 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.