Welcome back. Last time, you gave JavaScript scripts named values using const and let, and you chose appropriate primitive types such as string, boolean, number, and bigint. Now those booleans become useful: your code will inspect a situation and decide what should happen next.
Conditional logic is fundamental in blockchain programs. A wallet client may check whether it is connected to the expected network before submitting a transaction. A smart contract later checks whether a caller is authorized or whether an amount is valid. The syntax will differ slightly in Solidity, but the reasoning starts here.

By the end of this lesson, you will be able to write if, else if, and else branches; compare values correctly; combine conditions with logical operators; and avoid the common confusion between assignment (=) and equality (===). Plan for about 45 minutes.
Conditions are questions that produce booleans
A condition is an expression JavaScript can evaluate as either true or false.
const confirmations = 3;
console.log(confirmations >= 1); // true
console.log(confirmations >= 6); // false
The first question asks, “Are there at least one confirmation?” The answer is true. The second asks whether there are at least six; its answer is false.
An if statement uses that answer to decide whether to run a block of code:
const isWalletConnected = true;
if (isWalletConnected) {
console.log("Wallet is connected.");
}
Because isWalletConnected is true, Node runs the code inside the curly braces. If it were false, Node would skip that block.
When there are two possible outcomes, add else:
const isWalletConnected = false;
if (isWalletConnected) {
console.log("Wallet is connected.");
} else {
console.log("Connect a wallet before continuing.");
}
Only one branch runs: the if block when the condition is true, otherwise the else block.
Curly braces and indentation are not decoration. They show exactly which statements belong to each outcome. Use braces even for a one-line branch; it prevents mistakes when you add more code later.
Making decisions in your code — conditionals - MDN Web Docs
Read MDN Web Docs’ introduction to conditionals for the structure of if...else, multi-branch decisions, comparisons, and logical operators.
In “if...else statements,” read “Basic if...else syntax” and “else if.” Pay particular attention to why branches need braces: code placed after an if without an else is not automatically part of the alternative path. Then read “A note on comparison operators” and “Logical operators: AND, OR and NOT.” Focus on comparisons as boolean tests, followed by combining conditions. Skip the later switch and ternary sections for now.
Comparing values precisely
Comparison operators ask questions about values. Their result is always a boolean, which makes them suitable inside if (...).
| Question | Operator | Example | Result |
|---|---|---|---|
| Is the left value greater? | > |
confirmations > 0 |
true or false |
| Is it smaller? | < |
gasLimit < 21000 |
true or false |
| Is it at least this value? | >= |
confirmations >= 6 |
true or false |
| Is it at most this value? | <= |
amountWei <= balanceWei |
true or false |
| Are value and type the same? | === |
networkName === "sepolia" |
true or false |
| Are they different in value or type? | !== |
chainId !== expectedChainId |
true or false |
Here is a simple confirmation classifier:
const confirmations = 4;
if (confirmations >= 6) {
console.log("Transaction has six or more confirmations.");
} else {
console.log("Transaction has fewer than six confirmations.");
}
Notice the use of >=, not >. If six confirmations count as sufficient, the value 6 must pass the test.
= assigns; === compares
This distinction is essential:
let confirmations = 0;
confirmations = 3; // assignment: store 3 in the variable
confirmations === 3; // comparison: ask whether it is 3
A single equals sign, =, changes a variable. Three equals signs, ===, asks a question.
Do not write this:
if (confirmations = 3) {
console.log("Confirmed");
}
If confirmations were declared with let, this would overwrite its previous value with 3. The assignment itself evaluates to 3, which JavaScript treats as truthy, so the branch would run—silently producing the wrong behavior. This is one reason a careful use of const and strict comparisons is valuable.
Prefer strict equality: === and !==
JavaScript also has loose equality operators, == and !=. Avoid them in new code.
Loose equality can convert types before comparing:
console.log("1" == 1); // true
console.log("1" === 1); // false
The string "1" is not the number 1. Strict equality recognizes that distinction. In future blockchain tooling, data returned from an API or a form may arrive as a string even when it looks numeric. An accidental conversion can allow invalid data through a check.
The same principle applies to bigint:
console.log(1n === 1); // false
They represent related quantities, but 1n is a bigint and 1 is a number.
Comparisons - The Modern JavaScript Tutorial
Read the relevant sections of The Modern JavaScript Tutorial to see why strict equality is the safer default.
In “Comparison of different types,” read the examples showing how loose equality converts values. Then read “Strict equality.” Focus on the source of loose-equality surprises, and on the rule that === does not convert types before testing equality. Treat === and !== as your normal equality operators.
A practical blockchain-oriented rule is:
- Compare network names, addresses, hashes, and status labels with
===. - Compare amounts, counts, block heights, and fees with
>,<,>=, or<=, using compatible numeric types. - Do not compare addresses or transaction hashes with
<or>; they are identifiers stored as strings, not quantities with a meaningful numeric order.
More than two outcomes: else if
A transaction checker often has several possible outcomes. Use else if between the initial if and the final else.
const confirmations = 2;
if (confirmations >= 6) {
console.log("Confirmed.");
} else if (confirmations >= 1) {
console.log("Included, but awaiting more confirmations.");
} else {
console.log("Not yet included in a block.");
}
JavaScript tests each branch from top to bottom and runs the first condition that is true. It skips every branch after that.
Therefore, order matters. This version is wrong:
if (confirmations >= 1) {
console.log("Included, but awaiting more confirmations.");
} else if (confirmations >= 6) {
console.log("Confirmed.");
}
For a value of 6, the first condition is already true. JavaScript never reaches the more specific >= 6 check.
A useful pattern is:
- Put exceptional or most restrictive cases first.
- Put broader cases below them.
- Use
elsefor the remaining situation, when it genuinely makes sense.
Combining conditions with logical operators
One comparison is often not enough. A transaction can be valid only if several facts are true at once: perhaps the wallet is connected, the chain ID is expected, and the requested amount is within the available balance.
JavaScript provides three logical operators:
| Operator | Meaning | Result |
|---|---|---|
&& |
AND | true only if every condition is true |
| ` | ` | |
! |
NOT | reverses a boolean result |
AND: every requirement must pass
const amountWei = 500000000000000000n;
const balanceWei = 2000000000000000000n;
const hasValidAmount =
amountWei > 0n && amountWei <= balanceWei;
console.log(hasValidAmount); // true
The amount must be positive and no greater than the balance. If either check is false, the full && expression is false.
OR: at least one option is acceptable
const transactionStatus = "queued";
const isWaiting =
transactionStatus === "pending" ||
transactionStatus === "queued";
console.log(isWaiting); // true
Use || when either condition is enough.
A frequent beginner bug is incomplete testing:
// Incorrect: this is always true
if (transactionStatus === "pending" || "queued") {
console.log("Waiting");
}
The string "queued" is a non-empty string, which JavaScript treats as truthy. You must write a complete comparison on each side of ||:
if (
transactionStatus === "pending" ||
transactionStatus === "queued"
) {
console.log("Waiting");
}
NOT: reverse a boolean
! means “not.”
const isWalletConnected = false;
if (!isWalletConnected) {
console.log("Connect your wallet.");
}
The variable is false; !false becomes true, so the branch runs.
When a variable is already a clearly named boolean, direct checks are readable:
if (isWalletConnected) {
console.log("Ready to continue.");
}
if (!isWalletConnected) {
console.log("Connection required.");
}
Do not add === true unless it genuinely improves clarity. if (isWalletConnected) already asks the intended question.
Learn JavaScript LOGICAL OPERATORS in 5 minutes ❗
Watch “Learn JavaScript LOGICAL OPERATORS in 5 minutes” from Bro Code for a compact visual walkthrough of AND, OR, and NOT.
Begin with the overview to identify the three operators. Then watch AND, OR, and NOT. As you watch, translate each example into a blockchain check: all transaction requirements, alternative allowed statuses, and a missing wallet connection.
Build a transaction preflight checker
Create a file named transaction-check.js in your Node.js practice folder. This script is a local simulation: it does not contact Ethereum or submit a real transaction. Its job is to decide whether a hypothetical transaction request passes basic checks.
const expectedChainId = 11155111;
const connectedChainId = 11155111;
const isWalletConnected = true;
const balanceWei = 2000000000000000000n;
const amountWei = 500000000000000000n;
const transactionStatus = "pending";
if (!isWalletConnected) {
console.log("Connect a wallet before submitting a transaction.");
} else if (connectedChainId !== expectedChainId) {
console.log("Switch to the expected network.");
} else if (amountWei <= 0n) {
console.log("Enter an amount greater than zero.");
} else if (amountWei > balanceWei) {
console.log("Insufficient balance.");
} else {
console.log("Transaction request passes the basic checks.");
}
const canSubmit =
isWalletConnected &&
connectedChainId === expectedChainId &&
amountWei > 0n &&
amountWei <= balanceWei;
console.log("Can submit:", canSubmit);
if (
transactionStatus === "pending" ||
transactionStatus === "queued"
) {
console.log("Transaction is waiting for inclusion.");
} else if (transactionStatus === "confirmed") {
console.log("Transaction is confirmed.");
} else {
console.log("Transaction has an unrecognized status.");
}
Run it with:
node transaction-check.js
With the values shown, the output should be:
Transaction request passes the basic checks.
Can submit: true
Transaction is waiting for inclusion.
Now make these deliberate edits, one at a time, and rerun after each:
- Change
isWalletConnectedtofalse. The first branch should run, andcanSubmitshould becomefalse. - Restore the wallet connection, then change
connectedChainIdto1. The network mismatch branch should run. - Restore the chain ID, then set
amountWeito3000000000000000000n. The insufficient-balance branch should run. - Set
transactionStatusto"confirmed"and observe the laterelse ifbranch. - Set
transactionStatusto"failed"and observe the finalelsefallback.
This is the core debugging habit for conditional code: change one input, predict which condition should be first to become true, then verify the result in Node.
A short checklist for conditional code
Before running a condition, inspect it with this checklist:
- Does each comparison use
===,!==,<,>,<=, or>=rather than=? - Are both sides compatible types? For example, compare a
bigintamount to anotherbigintamount. - Does every branch do something distinct and meaningful?
- In an
else ifchain, are more specific conditions above broad ones? - With
&&, must all requirements really be met? With||, is either outcome genuinely acceptable? - Did you fully repeat the comparison on both sides of
||?
Wrap-up
You can now make JavaScript programs choose a path based on boolean conditions:
if,else if, andelsecontrol which block runs.- Comparison operators produce
trueorfalse. - Use strict equality—
===and!==—rather than loose equality. &&requires every condition,||accepts one or more conditions, and!reverses a boolean.- The order of an
if...else ifchain determines which matching branch wins.
These same decision patterns will later appear in Solidity as checks such as “is this caller allowed?” and “is this transaction state valid?” Next, you will use loops to process a defined sequence of values—useful when a script needs to inspect several items rather than make a decision about just one.