Expression Functions for Lightning Web Components

There are multiple options. First, note, that all computations are in JavaScript, not in the markup.

Option 1 You implement the display of your {item} (which is currently only the JSON object), into a dedicated component AccountListItem. And implement in there the logic that @POZ suggested.

Something along the lines of:

import {LightningElement, api} from 'lwc';

export default class AccountListItem extends LightningElement {
   @api index;
   @api item;

   get isMod5() {
     return this.index % 5 == 0;
   }
}

Option 2 You use a wired function instead of a wired property. And then do some fun stuff with a changed data model. Although this is hacky.

import {LightningElement, wire, track} from 'lwc';
import getAccounts from '@salesforce/apex/TestController.getAccounts';

export default class AccountList extends LightningElement {

    @wire(getAccounts)
    wiredAccounts({ error, data}) {
       if (error) {
         // do error handling, please
       } else if (data) {
         this.accounts = data.map((acct, index) => {
               return {
                  acct: acct,
                  isMod5: index % 5 == 0 ? true : false
               }
           })
       }
    }

EDIT: changed my answer because previous one was wrong:

You have to write a JS expression that paginates your list like this:

get getContacts() {
  return [
    { id: 0, items: ['a', 'b', 'c', 'd', 'e']}, // Page 0, max 5 item
    { id: 1, items: ['f', 'g']} // Page 1
  ];
}

Then use two iterations in your template:

<template for:each={getContacts} for:item="page">
  <div key={page.id}>
    <template for:each={page.items} for:item="contact">
      {contact}
    </template>
  </div>
</template>

Because expressions are not allowed in Lightning Web Component template, you would have required a JavaScript getter function here. Refer to HTML Template Directives documentation for details.

Excerpt below from documentation:

if:true|false={expression}

..... (some text omitted)

The engine doesn’t allow computed expressions. To compute the value of expression, use a getter in the JavaScript class.

But, in your case you need to pass the index var in the iteration, so even having a getter function doesn't seem to do the job here.


I am not completely sure of the use case here as why you want to utilize the index within the iteration, but as I don't see a way to set the index to a JS function, here's an approach that you can take by utilizing Composition.

Even though this approach solves the problem here, but still seems to be an overhead of creating another component to achieve this what could have been achieved inline.

The approach here is:

  • Create a custom LWC
  • Pass the index value to the component within the iteration in the parent component
  • Compute the value of the index within that component and perform your required operation

Let's say I create a custom LWC as c-my-index-component, which looks like as below:

<template>
    <template if:true={indexVar}>
        // do something
    </template>
</template>

In the JS, I have this property defined as:

import { LightningElement, api, track } from 'lwc';
export default class MyCustomIndex extends LightningElement {
    @track myVariable;

    set indexVar(value) {
        this.myVariable = value;
    }

    @api
    get indexVar() {
        return (this.myVariable % 5 === 0)
    }
}

And then finally I use it in my existing component in iteration as below:

<template for:each={accounts.data} for:item='item' for:index='index'>
    <c-my-index-component key={item.Id} index-var={index}></c-my-index-component>
     // my other code
</template>