100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Conditionals in Dart

Learn how Dart evaluates branching logic using if/else, switch statements with Dart 3 pattern matching, and compact conditional expressions like the ternary and null-aware operators.

Control Flow & FunctionsBeginner8 min readJul 10, 2026
Analogies

Introduction to Conditional Logic in Dart

Conditional statements let a Dart program choose which block of code to execute based on whether a boolean expression evaluates to true or false. Dart is statically typed, so every condition in an if statement must evaluate to a bool — unlike JavaScript, Dart does not implicitly convert numbers or strings to booleans, which eliminates a common class of bugs. Conditionals are the foundation for input validation, state transitions, and UI logic in Flutter widgets, where a build method often decides which widget tree to render based on app state.

🏏

Cricket analogy: Before deciding to review a decision, the on-field umpire's soft signal acts like Dart's boolean condition — everything downstream (DRS, third umpire) only runs if that initial true/false check is made, exactly as an if statement gates a block of code.

The if, else if, and else Statements

The if statement executes a block only when its condition is true, else if lets you chain additional mutually exclusive checks, and else provides a fallback when none of the earlier conditions matched. Dart evaluates the conditions top to bottom and stops at the first true branch, so ordering matters when ranges overlap, such as when checking a score against multiple grade thresholds. Because condition expressions can contain any boolean-returning code, including function calls and comparisons combined with && and ||, if-chains scale naturally to complex business rules.

🏏

Cricket analogy: A match referee checking overs bowled runs through ordered checks — first is it a no-ball, else if it's a wide, else it's a legal delivery — evaluating conditions top to bottom exactly like Dart's if/else if/else chain, stopping at the first match.

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

The switch Statement and Pattern Matching

Dart 3 significantly expanded the switch statement beyond simple value matching: it now supports pattern matching, destructuring, and guard clauses using the when keyword, letting you match against object shapes, list structures, and record types in a single case. A switch statement requires cases to be exhaustive or include a default branch when using enums or sealed classes, and the analyzer will warn about unreachable or non-exhaustive cases, catching mistakes that a chain of if statements would let slip through silently. The newer switch expression form returns a value directly, replacing verbose assignment patterns.

🏏

Cricket analogy: Selecting the bowling attack for an over is like a switch statement matched on pitch condition — case 'dry and cracked': bring on the spinner; case 'green and seaming': the pace bowler; each case handling one distinct, exhaustive scenario rather than a chain of loose guesses.

dart
sealed class Shape {}
class Circle extends Shape { final double radius; Circle(this.radius); }
class Square extends Shape { final double side; Square(this.side); }

double area(Shape shape) => switch (shape) {
  Circle(radius: var r) => 3.14159 * r * r,
  Square(side: var s) => s * s,
};

void describeAge(int age) {
  final label = switch (age) {
    < 13 => 'child',
    >= 13 && < 20 => 'teenager',
    _ when age >= 65 => 'senior',
    _ => 'adult',
  };
  print(label);
}

Since Dart 3, marking a class hierarchy as sealed lets the compiler verify that a switch statement handles every subtype, so adding a new subclass later triggers a compile error everywhere its switch isn't updated — a powerful safety net for large codebases.

Conditional Expressions: Ternary and Null-aware Operators

Beyond full if statements, Dart offers compact conditional expressions for use inside larger expressions: the ternary operator condition ? expr1 : expr2 picks between two values inline, while the null-aware operators ?? and ??= provide a default when a nullable value is null, and ?. safely accesses a member only if the receiver isn't null. These operators are especially common in Flutter widget trees, where you might write isLoading ? CircularProgressIndicator() : ListView(...) directly inside a build method rather than pulling the logic into a separate if statement.

🏏

Cricket analogy: A scoreboard operator updates the 'required run rate' figure inline with a quick mental ternary — target reached ? show 'WON' : compute rate — a compact, single-glance decision just like Dart's condition ? a : b embedded directly inside an expression.

Nesting ternary operators more than one level deep quickly becomes unreadable — a ? (b ? c : d) : e forces the reader to mentally parse branch priority. Prefer an if/else chain, a switch expression, or extracting a named function once a conditional expression stops fitting comfortably on one line.

  • if/else if/else evaluate conditions top to bottom and run only the first matching branch.
  • Every condition must be a strict bool — Dart never implicitly converts numbers or strings to booleans.
  • switch statements support pattern matching, destructuring, and guard clauses (when) since Dart 3.
  • Sealed classes let the analyzer enforce exhaustive switch cases at compile time.
  • The ternary operator (condition ? a : b) and null-aware operators (??, ??=, ?.) express simple decisions inline.
  • Deeply nested ternaries hurt readability — prefer if/else or switch expressions once logic grows complex.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#DartStudyNotes#ConditionalsInDart#Conditionals#Dart#Conditional#Logic#StudyNotes#SkillVeris#ExamPrep