javascriptcomponentsstenciljs

StencilJS Component - Passing an Array of Objects as Prop into Component


I am creating a list component where I pass an array with the data.

html

<ps-list>

I insert the array with the following JS:

const listCollection = [
        {label: "Link One"},
        {label: "Link Two"},
        {label: "Link Three"},
        {label: "Link Four"}
]
document.querySelector('ps-list').listItems = listCollection

My prop is setup like this:

@Prop() listItems: object[]

THE ISSUE: I am using map to iterate through the object in order to populate a list.

this.listItems.map((item: object) => {
    console.log(item.label)
})

The problem comes up if I try to access the value of label in the console.log shown above.

The error I get is: "Property 'label' does not exist on type 'object'"

Normally that is the correct way to get the value.

If I do console.log(typeof item) the browser console shows that it is an object.

How can I get the value of "label" in my array of objects?


Solution

  • The problem in this case is the types, the object type doesn't have a label field.

    I would solve it by creating a more specific type for that property (which you will need to extend if you add new properties to the object):

    // outside the component class:
    export interface ListItem {
      label: string;
    }
    
    // and in the component:
    
    @Prop() listItems: ListItem[];
    

    Note that I'm also exporting the type. You don't have to do that, but it can be helpful to other users of this component.

    Another option would be adding the type inline:

    @Prop() listItems: { label: string}[];
    

    And if you don't care about the types you can use any (which I wouldn't recommend):

    @Prop() listItems: any[];
    // or even this
    @Prop() listItems: any;
    

    By the way, there's a trick I wish I knew when I started learning TypeScript: If you have an error on a line, try adding this on the line before:

    // @ts-ignore
    

    This will (temporarily) ignore all type errors on the next line, so you can test if the JavaScript part works. If it does then you know that TypeScript is the source of the problem, not the runtime/JS code. But I recommend removing it before you commit/release as it could also hide runtime problems.

    UPDATE

    There used to be a problem in Stencil where you couldn't (or shouldn't) export multiple things from component files. Create a separate separate file and export it from there instead, and then import it in your component.