JavaScript in LWC: The Basics · Lesson 3 of 25
Operators and Conditional Logic in LWC
Because LWC templates have no expressions, every "show this when…" rule ends up in a JavaScript getter. lwc:if takes a property, and your getter decides whether it's true. That makes operators and conditionals the JavaScript you'll write most often – and getting them slightly wrong is the source of many "why is this section not showing?" bugs.
In this lesson
- === vs == and the falsy values
- Optional chaining and nullish coalescing
- &&, ||, ternaries and logical assignment
- if/else, switch and lookup objects in getters
Always compare with ===
console.log(0 == '', null == undefined, '1' == 1); // == converts types first
console.log(0 === '', null === undefined, '1' === 1); // === compares type and value
const stage = 'Closed Won';
console.log(stage === 'Closed Won', stage === 'closed won');
console.log(stage.toLowerCase() === 'closed won');
true true true false false false true false true
Use === and !== everywhere. The one widely accepted exception is value == null, a short way to check for both null and undefined.
Truthy and falsy
Conditions convert values to booleans. These eight values are falsy; everything else – including '0', 'false', [] and {} – is truthy:
Falsy values
- falseboolean
- 0zero
- -0negative zero
- 0nBigInt zero
- ""empty string
- nullempty
- undefinednot set
- NaNnot a number
const contacts = [];
if (contacts) console.log('an empty array is truthy!');
console.log(contacts.length > 0 ? 'has contacts' : 'no contacts'); // test the length instead
console.log(Boolean('false'), Boolean(0), !!'Acme');
an empty array is truthy! no contacts true false true
Getters for lwc:if should return real booleans
get hasContacts() { return this.contacts.length > 0; } is clear and safe. Returning the array itself (return this.contacts;) makes an empty list truthy and shows the section anyway.
Optional chaining (?.) and nullish coalescing (??)
const opp = { Name: 'Acme renewal', Account: null, Amount: 0, Probability: undefined };
console.log(opp.Account?.Name); // undefined instead of a TypeError
console.log(opp.Account?.Owner?.Name ?? 'No owner');
console.log(opp.Amount ?? 'n/a', opp.Probability ?? 'n/a');
console.log(opp.Contacts?.[0]?.Email ?? 'No contacts'); // ?. also works with [] and ()
console.log(opp.format?.() ?? 'no format method');
try {
console.log(opp.Account.Name); // without ?.
} catch (e) {
console.log(e.constructor.name + ': ' + e.message);
}
undefined No owner 0 n/a No contacts no format method TypeError: Cannot read properties of null (reading 'Name')
The "Cannot read properties of null" error is the most common runtime error in LWC – usually from data.fields.Account.value.fields.Name paths or a wire result that hasn't arrived yet. ?. stops at the first null or undefined and returns undefined.
&&, || and the ternary
const user = { isAdmin: false, profile: 'Sales User', nickname: '' };
console.log(user.isAdmin && 'Delete enabled'); // && returns the first falsy value…
console.log(user.profile && `Profile: ${user.profile}`); // …or the last value
console.log(user.nickname || 'Guest'); // || returns the first truthy value
console.log(JSON.stringify(user.nickname ?? 'Guest')); // ?? keeps the empty string
const score = 72;
const band = score >= 80 ? 'Hot' : score >= 50 ? 'Warm' : 'Cold';
console.log(band);
// logical assignment: set a default only if missing
const filters = { stage: 'Prospecting' };
filters.pageSize ??= 25;
filters.stage ||= 'All';
console.log(filters);
false
Profile: Sales User
Guest
""
Warm
{ stage: 'Prospecting', pageSize: 25 }
Use ternaries for simple two-way choices in getters. Once you nest more than one, switch to if statements or a lookup object – your reviewers will thank you.
if/else, switch and lookup objects
Here's a component that turns a case priority into a badge. It shows three ways to branch, all inside getters:
// casePriority.js
import { LightningElement, api } from 'lwc';
const BADGE_CLASS = { // lookup object: data instead of branches
High: 'slds-theme_error',
Medium: 'slds-theme_warning',
Low: 'slds-theme_success',
};
export default class CasePriority extends LightningElement {
@api priority;
@api hoursOpen = 0;
get badgeClass() {
return `slds-badge ${BADGE_CLASS[this.priority] ?? 'slds-badge_lightest'}`;
}
get slaText() {
switch (this.priority) {
case 'High':
return 'Respond within 1 hour';
case 'Medium':
return 'Respond within 8 hours';
default:
return 'Respond within 2 days';
}
}
get isOverdue() {
if (this.priority === 'High') return this.hoursOpen > 1;
if (this.priority === 'Medium') return this.hoursOpen > 8;
return this.hoursOpen > 48;
}
}
<!-- casePriority.html -->
<template>
<span class={badgeClass}>{priority}</span>
<p>{slaText}</p>
<template lwc:if={isOverdue}>
<p>⚠ SLA breached</p>
</template>
<template lwc:else>
<p>Within SLA</p>
</template>
</template>
High Respond within 1 hour Within SLA › parent sets hoursOpen = 3 High Respond within 1 hour ⚠ SLA breached › parent sets priority = "Low" Low Respond within 2 days Within SLA
- Lookup objects replace long
if/switchchains when you map one value to another – and they're easy to extend. switchuses===; don't forgetreturnorbreakin each case.- Early returns keep
iflogic flat and readable.
Practice
Try it yourself
Write a getter
showDiscountSectionthat is true only when the user is a manager and the opportunity amount is at least 100000 (Amount may be missing).Show answer
get showDiscountSection() { return this.isManager === true && (this.opp?.Amount ?? 0) >= 100000; }– it always returns a boolean, and a missing amount counts as 0.What do
'' || 'x'and'' ?? 'x'return?Show answer
'x'and''. || skips any falsy value; ?? only skips null and undefined.
Quick check
Is an empty array truthy?
Yes – check array.length instead.
What does a?.b return when a is null?
undefined, without throwing.
What does x ??= 5 do?
Assigns 5 only if x is null or undefined.
Summary
- Use === and !==; value == null is the one handy exception.
- Know the falsy values; test array length, not the array.
- ?. prevents "Cannot read properties of null"; ?? keeps 0 and '' as real values.
- Put conditions in getters that return booleans; prefer lookup objects to long chains.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.