3

It is ok to retrieve the elements of a List<String> in Javascript controller in LWC as below:

@wire(getListOfString)wrappers({error, data}) {
  if(data){
    this.stringList = data;
    this.str0 = data[0];
    this.str1 = data[1];
    this.str2 = data[2];
  }else{
    this.error = error;
  }
}

And it is ok to display {str0}, {str1}, {str2} in the HTML file.

In other words, {stringList} is a List<String> and it works well in the Javascript controller.

But, it does not work in the HTML file.

I've tried to use {stringList[0]}, {stringList[1]}, {stringList[2]} in the HTML file directly. And, it is not ok.

It is not ok to use {stringList}[0], {stringList}[1], {stringList}[2], neither.

Could it be able to retrieve the element from List in HTML file directly? Or, it can not work in this way.

== Use case ==

Think of a use case for which the output of LWC depends on serval factors. In the case, I prefer to retrieve those factors to a List with a single Apex class.

And, if the conventions support {strings[n]} syntax in the template file, (where {string[n]} is a specific factor) then it will be easiler to control the dynamic/factor-dependent LWC.

1

3 Answers 3

1

You can use for:each for this.

<template for:each={stringList} for:item="eachString">
  {eachString}
</template>

But you cannot use expressions in LWC templates. for eg: {strings[0]} or {strings}[0] is NOT ALLOWED

8
  • Please help to confirm it is not possible to access "specfic" element of the list (array) in the LWC html file.
    – Cray Kao
    Commented Jan 4, 2021 at 11:43
  • 2
    specific elements of list such as {strings[0]} or {strings}[0] are not allowed in html file. Commented Jan 4, 2021 at 12:23
  • Whoever downvoted? Can you please share a reason for downvoting the above answer. Commented Jan 4, 2021 at 16:27
  • The question is titled "How to access the specific element from List<String> in HTML <template> file directly in LWC?" and you didn't answer that question.
    – stackasaur
    Commented Jan 4, 2021 at 16:35
  • 1
    As you commented There is no way to access a specific element of an array in the template without hard coding it. so I provided a solution without hardcoding it. There is no reason to downvote. Commented Jan 4, 2021 at 16:41
0

For some reason, the other answer didn't provide a solution for you...

If you NEED to access specific elements, you should make use of getters.

So rather than storing them as their own variables via str0, str1 ... strN, use a getter to access them.

Let's say we want to output the 4th element:

get fourthItem(){
  return (this.stringList && this.stringList.length >= 4)? this.stringList[3]:null;
}

so in your template, you'd just call the getter

<p>{fourthItem}</p>

This way, we also provide a level of error checking. We ensure that stringList is defined and that the fourth element exists.

3
  • Even this seems like hard-coding. The question is Could it be able to retrieve the element from List in HTML file directly? Or, it can not work in this way. The answer is NO. Your solution and the solution in question both are kind of identical, in which developer has to hard-code each and every element he is trying to fetch. Commented Jan 4, 2021 at 16:31
  • There is no way to access a specific element of an array in the template without hard coding it. I instead provided a solution that accomplishes the goal and has error checking.
    – stackasaur
    Commented Jan 4, 2021 at 16:37
  • Even when the user is doing this.str1 its the same. Commented Jan 4, 2021 at 16:42
0

Like what @stackasaur said, your best option is to use a getter. You can simplify the getter with:

get fourthItem(){
   return this.stringList?.at(3);
}

If you really need a way to retrieve items from the array in a dynamically, another option is to make your array into an object:

get myListAsObj(){
    return this.stringList?.reduce((obj, item, index) => {
        obj['index' + index] = item;
        return obj;
    }, {}) ?? {}; // Returns {} when undefined to safely reference properties in template before this.stringList is assigned
}

And in your template:

<h1>{myListAsObj.index0}</h1> <!-- this.stringList[0] -->
<h1>{myListAsObj.index1}</h1> <!-- this.stringList[1] -->
<h1>{myListAsObj.index2}</h1> <!-- this.stringList[2] -->
<h1>{myListAsObj.index3}</h1> <!-- this.stringList[3] -->
<h1>{myListAsObj.index4}</h1> <!-- this.stringList[4] -->
...

Keep in mind, the getter function will run every time you reference this.myListAsObj which can be expensive for larger arrays. If your array data doesn't change after being retrieved, you could forgo the getter and simply assign the object once - this route requires you to keep your array and object data synced.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .