0

I am playing around the Angular Elements to see if I can create a web components using existing Angular components so I can share the component between different frameworks. I have created a simple web component using Angular Elements that should take as an input an array of objects and display something like a list. I was able to compile however when I hooked it to simple HTML page I am getting following error:

ERROR Error: "Error trying to diff '[object Object],[object Object],[object Object]'. Only arrays and iterables are allowed"

My page looks like this:

  <head>    
    <title>Angular Element Component in HTML</title>
  </head>
  <body>
    <base href=".">
    <script src="elements/myCustomElements.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="elements/styles.css">


    <app-my-custom-element>

    </app-my-custom-element>

    <script type="text/javascript">
    let testData = [
    {
        name: 'Test Name 1',
        value: 'test1'
    },
    {
        name: 'Test Name 2',
        value: 'test 2'
    },
    {
        name: 'Test Name 3',
        value: 'test 3'
    }];

    const appMyCustomElement = document.getElementsByTagName('app-my-custom-element');

    if(appMyCustomElement.length>0){
      const target = appMyCustomElement[0];

      target.setAttribute('users', testData);
      target.addEventListener('search', (e) => testData.push({
        name: e,
        value: 'test'
      }));
    }
  </script>
  </body>
</html>

Is there any ease way to indicate to Angular Elements component that this is an array?

CLARIFICATION: The code I insert here is not Angular but pure HTML. I have a separate application in Angular that is getting "compiled" as Angular Elements webcomponent. After "compilation" process I would end up with 2 files: myCustomElement.js & styles.css. These files could be referenced now in a completely random app written in React, Vue or even pure HTML. The code that you see is a pure HTML page that is attempting to use my webcomponent

The solution I have now that I do not like: In the HTML page populate when setting attribute pass it as json:

<html>
  <head>    
    <title>Angular Element Component in HTML</title>
  </head>
  <body>
    <base href=".">
    <script src="elements/myCustomElements.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="elements/styles.css">


    <app-my-custom-element>

    </app-my-custom-element>

    <script type="text/javascript">
    let testData = [
    {
        name: 'Test Name 1',
        value: 'test1'
    },
    {
        name: 'Test Name 2',
        value: 'test 2'
    },
    {
        name: 'Test Name 3',
        value: 'test 3'
    }];

    const appMyCustomElement = document.getElementsByTagName('app-my-custom-element');

    if(appMyCustomElement.length>0){
      const target = appMyCustomElement[0];

      target.setAttribute('users', JSON.stringify(testData));
      target.addEventListener('search', (e) => {
            let currentData = JSON.parse(target.getAttribute('users'));
            currentData.push({
                name: e.detail,
                value: 'test'
      });

      target.setAttribute('users', JSON.stringify(currentData));
    }
  </script>
  </body>
</html>

In the Angular app I have to convert json to the object like:


  convertedUsers: IUserInfo[] = [];

  @Input() set users(value: string) {
    console.warn(value);
    this.convertedUsers = JSON.parse(value) as IUserInfo[];
  }

  get users(): string {
    return JSON.stringify(this.convertedUsers);
  }

  @Output() search = new EventEmitter<string>();
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
AlexanderM
  • 1,613
  • 4
  • 21
  • 35
  • Did you find a solution to this problem? I'm experiencing the same: I'm using an Angular Element in an AngularJS app. – J.Porras Nov 12 '20 at 15:20
  • @J.Porras, the only solution I have is the one I mentioned in the question: pass it on as serialized object and then element is deserializing it to the object. It is very possible that there is a better solution, however since then I did not had a chance to have a use for the Angular Elements since we only needed to share few minor things between Angular and non-Angular apps so we did got away with this solution. – AlexanderM Nov 15 '20 at 18:19

0 Answers0