Search code examples
javascripttypescriptrenderlit-element

lit-element: can't get an array of objects to render output in loop


Just starting with lit-element

in my render i have:

  return html`
   ${this.jobCreate}
   ${this.jobDetails}
  `;

get jobCreate works fine

this is my get jobDetails:

  get jobDetails() {
    const jobs = [
      { name: "phoenix job", location: "phoenix", expires: "2020-10-01" },
      { name: "chicago job", location: "chicago", expires: "2020-10-01" },
      { name: "pittsburgh job", location: "pittsburgh", expires: "2020-10-01" },
    ];

    return html`<ul>
      ${jobs.forEach((job) => html`<li>${job.name}</li>`)}
    </ul>`;
  }

inspecting the element i can see an empty <ul> set

if do a <ul><li>${jobs[2].name}</li></ul> that works

if i console out job, i can see all the right job print 3 times in the loop

I can't understand why i can't get the <li> to render in the loop

i used this for reference: https://lit-element.polymer-project.org/guide/templates#template-syntax-cheat-sheet


Solution

  • You're using forEach instead of map for looping the jobs array. forEach returns undefined whereas map returns a new array with every value mapped according to the function given.

    As an alternative way of thinking about it, if you took out the template literal tags and output a string 'undefined' when a value is undefined, forEach will output the following:

    <ul>
         undefined
    </ul>
    

    whereas map would output:

    <ul>
        <li>phoenix job</li><li>chicago job</ul><ul>pittsburgh job</ul>
    </ul>
    

    The following is likely what you're aiming for:

    get jobDetails() {
        const jobs = [
            { name: "phoenix job", location: "phoenix", expires: "2020-10-01" },
            { name: "chicago job", location: "chicago", expires: "2020-10-01" },
            {
                name: "pittsburgh job",
                location: "pittsburgh",
                expires: "2020-10-01",
            },
        ];
    
        return html`<ul>
            ${jobs.map((job) => html`<li>${job.name}</li>`)}
        </ul>`;
    }
    
    

    Further reading: