Expression Functions in LWC?
Question:
How can expression functions, similar to those in Visualforce and Aura Components, be used in Lightning Web Components (LWC)?
For example, in Aura and Visualforce, inline expressions are commonly used, but in LWC, expressions like the one below fail to compile:
<template if:true={index % 5 == 0}><br></template>Consider the following LWC component:
accountList.html
<template>
<template if:true={accounts.data}>
<template for:each={accounts.data} for:item="item" for:index="index">
<!--<template if:true={index % 5 == 0}><br></template>-->
{item}
</template>
</template>
</template>accountList.js
import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/TestController.getAccounts';
export default class AccountList extends LightningElement {
@wire(getAccounts) accounts;
}Since LWC does not support inline expressions in templates, how can this be achieved in a clean and efficient way?
Answer:
LWC enforces a strict separation of logic and markup, meaning inline expressions are not allowed in the template. Instead, logic must be handled in JavaScript using getters.
For example
the condition {index % 5 == 0} should be written as a getter:
get isMultipleOfFive() {
return this.index % 5 === 0;
}And then referenced in the template:
<template i:true={isMultipleOfFive}><br></template>This approach improves readability, avoids complex inline expressions, and ensures better maintainability.
However, in cases where multiple boolean conditions are required, defining numerous getters can become cumbersome. Some developers have experimented with a more flexible approach using custom components.
One such approach is using a custom directive-like component to handle expressions declaratively.
Example
Example of a reusable <c-lwc-if> component that evaluates JavaScript expressions:
<c-lwc-if condition="(this.a == this.b) && (this.c == 6 || this.b == 'easypeasy')" scope={scope}>
<div slot="if">Render some HTML</div>
<div slot="else">Render some other HTML</div>
</c-lwc-if>Here, the condition property is evaluated in JavaScript within a controlled scope.
Another approach is to implement a switch-case component to handle multiple conditional cases dynamically:
<c-lwc-switch expression="this.a" scope={scope}>
<c-lwc-case value="4">
<div>Print Something</div>
</c-lwc-case>
<c-lwc-case value="5">
<div>Print Something else</div>
</c-lwc-case>
<c-lwc-case value="'test'">
<div>Print test</div>
</c-lwc-case>
<c-lwc-case default>
<div>Print Default</div>
</c-lwc-case>
</c-lwc-switch>And in JavaScript:
get scope() {
return {
a: this.b
};
}
