Lesson 15 min

if / else — Decision Making

00:00 / 00:00

if / else — Decision Making

Every useful program needs to make decisions. Should we show a welcome message or an error? Is the user old enough? Did the login succeed? These are all conditional situations — and in Dart, we handle them with if, else if, and else.


🔹 The Basic if Statement

The simplest form: run a block of code only if a condition is true.

dart
void main() { int age = 20; if (age >= 18) { print('You are an adult.'); } }
  • The condition inside () must evaluate to a bool (true or false).
  • The block inside {} runs only when the condition is true.
  • If the condition is false, the block is simply skipped.

🔹 if-else

Use else to handle the case when the condition is false.

dart
void main() { int age = 15; if (age >= 18) { print('Access granted.'); } else { print('Access denied. You must be 18+.'); } }

Output: Access denied. You must be 18+.

Tip: Always use curly braces {} even for single-line blocks. It prevents hard-to-find bugs when you add lines later.


🔹 if-else if-else Chains

When you have more than two possibilities, chain multiple conditions:

dart
void main() { int score = 75; if (score >= 90) { print('Grade: A'); } else if (score >= 80) { print('Grade: B'); } else if (score >= 70) { print('Grade: C'); } else if (score >= 60) { print('Grade: D'); } else { print('Grade: F'); } }

Output: Grade: C

Dart checks each condition top to bottom and executes only the first block whose condition is true. The rest are skipped.


🔹 Boolean Conditions

Conditions must be bool in Dart. Unlike JavaScript or C, Dart does not treat 0, null, or empty strings as false.

dart
void main() { bool isLoggedIn = true; // Correct — using a bool directly if (isLoggedIn) { print('Welcome back!'); } // ERROR in Dart — non-boolean used as condition // int x = 0; // if (x) { ... } // This does NOT compile! }

🔹 Relational Operators in Conditions

OperatorMeaning
==Equal to
!=Not equal to
>Greater than
<Less than
>=Greater than or equal
<=Less than or equal
dart
void main() { int a = 10, b = 20; if (a != b) { print('a and b are different'); } if (a <= b) { print('a is less than or equal to b'); } }

🔹 Logical Operators in Conditions

Combine multiple conditions using logical operators:

OperatorMeaning
&&AND — both must be true
||OR — at least one must be true
!NOT — flips true/false
dart
void main() { int age = 25; bool hasTicket = true; // AND — both conditions must be true if (age >= 18 && hasTicket) { print('You may enter the event.'); } // OR — at least one must be true bool isAdmin = false; bool isModerator = true; if (isAdmin || isModerator) { print('You have elevated access.'); } // NOT — flip a condition bool isBanned = false; if (!isBanned) { print('Account is active.'); } }

🔹 Nested if Statements

You can place if statements inside other if blocks:

dart
void main() { bool hasAccount = true; String password = 'secret123'; if (hasAccount) { if (password == 'secret123') { print('Login successful!'); } else { print('Wrong password.'); } } else { print('Please create an account first.'); } }

Warning: Avoid deep nesting! More than 2–3 levels of nested if statements makes code very hard to read and maintain. Consider refactoring with early returns or helper functions.


🔹 Common Patterns

Range Check

dart
void main() { int temperature = 22; if (temperature >= 20 && temperature <= 30) { print('Comfortable temperature.'); } else if (temperature < 20) { print("It's cold. Grab a jacket!"); } else { print("It's hot. Stay hydrated!"); } }

Null Check

dart
void main() { String? username; // nullable String if (username != null) { print('Hello, $username!'); } else { print('Hello, Guest!'); } }

Type Check with is

Use the is keyword to check the runtime type of a variable:

dart
void main() { dynamic value = 42; if (value is int) { print('It is an integer: $value'); } else if (value is String) { print('It is a string: $value'); } else { print('Unknown type'); } }

After if (value is int), Dart smart-casts value to int automatically inside that block — no explicit casting needed!


🔹 Real-World Examples

Example 1: Age Verification

dart
void checkAge(int age) { if (age < 0) { print('Invalid age.'); } else if (age < 13) { print('Child'); } else if (age < 18) { print('Teenager'); } else if (age < 65) { print('Adult'); } else { print('Senior'); } } void main() { checkAge(10); // Child checkAge(17); // Teenager checkAge(30); // Adult checkAge(70); // Senior }

Example 2: Grade System

dart
String getGrade(int score) { if (score < 0 || score > 100) { return 'Invalid score'; } else if (score >= 90) { return 'A — Excellent'; } else if (score >= 80) { return 'B — Good'; } else if (score >= 70) { return 'C — Average'; } else if (score >= 60) { return 'D — Below Average'; } else { return 'F — Fail'; } } void main() { print(getGrade(95)); // A — Excellent print(getGrade(73)); // C — Average print(getGrade(45)); // F — Fail }

Example 3: Login Validation

dart
void login(String username, String password) { if (username.isEmpty || password.isEmpty) { print('Username and password are required.'); return; } if (username.length < 3) { print('Username must be at least 3 characters.'); return; } if (password.length < 6) { print('Password must be at least 6 characters.'); return; } // If all checks pass: print('Credentials look valid. Logging in...'); } void main() { login('', 'pass'); // Username and password are required. login('ab', 'password'); // Username must be at least 3 characters. login('alice', '123'); // Password must be at least 6 characters. login('alice', 'secret'); // Credentials look valid. Logging in... }

Note: Using early return inside an if block (called a guard clause) is a great way to flatten nested conditions and make your code more readable.


Summary

ConceptPurpose
ifRun code only when condition is true
elseHandle the false case
else ifCheck multiple conditions in sequence
&&, ||, !Combine or negate boolean conditions
isCheck the runtime type of a variable
Nested ifConditional logic inside another condition
Guard clausesEarly returns to avoid deep nesting

Mastering if/else is the foundation of all program logic. In the next lesson, we'll explore switch statements and Dart 3's powerful pattern matching for cleaner multi-branch logic!

WhatsApp