Question #27MediumFlutter Basics

Diff btw if else and switch case in flutter

#flutter

Answer

Overview

if-else and switch-case are both conditional control structures in Dart/Flutter, but they have different use cases, syntax, and performance characteristics.


Comparison Table

Featureif-elseswitch-case
SyntaxBoolean conditionsEquality checks
FlexibilityHigh (any condition)Limited (exact matches)
ReadabilityGood for 2-3 branchesBetter for 4+ branches
PerformanceSlower (sequential)Faster (jump table)
Break RequiredNoYes
Fall-throughNoYes (with continue)
Use CaseComplex conditionsFixed values
Null SafetyBuilt-inRequires null check

if-else Statement

Syntax

dart
if (condition) {
  // Code if true
} else if (anotherCondition) {
  // Code if second condition true
} else {
  // Code if all false
}

Examples

dart
// Simple if-else
int age = 25;
if (age >= 18) {
  print('Adult');
} else {
  print('Minor');
}

// Multiple conditions
int score = 85;
if (score >= 90) {
  print('Grade: A');
} else if (score >= 80) {
  print('Grade: B');
} else if (score >= 70) {
  print('Grade: C');
} else {
  print('Grade: F');
}

// Complex conditions
bool isLoggedIn = true;
bool isPremium = false;

if (isLoggedIn && isPremium) {
  print('Premium user');
} else if (isLoggedIn && !isPremium) {
  print('Free user');
} else {
  print('Guest');
}

// Ternary operator (shorthand)
String status = age >= 18 ? 'Adult' : 'Minor';

When to Use if-else

  • ✅ Range checks (age >= 18)
  • ✅ Complex boolean logic (&&, ||)
  • ✅ Null checks
  • ✅ Type checks (is, is!)
  • ✅ 2-3 conditions
  • ✅ Different comparison operators (<, >, !=)

switch-case Statement

Syntax

dart
switch (expression) {
  case value1:
    // Code
    break;
  case value2:
    // Code
    break;
  default:
    // Code if no match
}

Examples

dart
// Basic switch-case
String day = 'Monday';
switch (day) {
  case 'Monday':
    print('Start of week');
    break;
  case 'Friday':
    print('End of week');
    break;
  case 'Saturday':
  case 'Sunday':
    print('Weekend');
    break;
  default:
    print('Midweek');
}

// With integers
int month = 3;
switch (month) {
  case 1:
  case 2:
  case 12:
    print('Winter');
    break;
  case 3:
  case 4:
  case 5:
    print('Spring');
    break;
  case 6:
  case 7:
  case 8:
    print('Summer');
    break;
  default:
    print('Fall');
}

// With enums
enum Status { loading, success, error }

Status currentStatus = Status.success;
switch (currentStatus) {
  case Status.loading:
    print('Loading...');
    break;
  case Status.success:
    print('Success!');
    break;
  case Status.error:
    print('Error occurred');
    break;
}

When to Use switch-case

  • ✅ Exact value matching
  • ✅ 4+ fixed options
  • ✅ Enums
  • ✅ String/int constants
  • ✅ Better readability for many branches
  • ✅ Performance-critical code

Flutter Widget Examples

Using if-else in Widgets

dart
class ProfileScreen extends StatelessWidget {
  final bool isLoggedIn;
  final bool isPremium;
  
  const ProfileScreen({
    required this.isLoggedIn,
    required this.isPremium,
  });
  
  
  Widget build(BuildContext context) {
    // Method 1: if-else statement
    Widget content;
    if (!isLoggedIn) {
      content = LoginButton();
    } else if (isPremium) {
      content = PremiumDashboard();
    } else {
      content = FreeDashboard();
    }
    
    return Scaffold(
      body: content,
    );
  }
}

// Method 2: Conditional expression in widget tree
class StatusWidget extends StatelessWidget {
  final int temperature;
  
  const StatusWidget(this.temperature);
  
  
  Widget build(BuildContext context) {
    return Container(
      color: temperature > 30 
          ? Colors.red 
          : temperature > 20 
              ? Colors.orange 
              : Colors.blue,
      child: Text('Temperature: $temperature°C'),
    );
  }
}

Using switch-case in Widgets

dart
enum ViewState { loading, loaded, error, empty }

class DataScreen extends StatelessWidget {
  final ViewState state;
  
  const DataScreen({required this.state});
  
  
  Widget build(BuildContext context) {
    Widget content;
    
    switch (state) {
      case ViewState.loading:
        content = CircularProgressIndicator();
        break;
      case ViewState.loaded:
        content = DataList();
        break;
      case ViewState.error:
        content = ErrorWidget('Failed to load');
        break;
      case ViewState.empty:
        content = Text('No data available');
        break;
    }
    
    return Scaffold(
      body: Center(child: content),
    );
  }
}

// Theme switcher
class ThemeSelector extends StatelessWidget {
  final String theme;
  
  const ThemeSelector(this.theme);
  
  
  Widget build(BuildContext context) {
    Color backgroundColor;
    
    switch (theme) {
      case 'light':
        backgroundColor = Colors.white;
        break;
      case 'dark':
        backgroundColor = Colors.black;
        break;
      case 'blue':
        backgroundColor = Colors.blue;
        break;
      default:
        backgroundColor = Colors.grey;
    }
    
    return Container(color: backgroundColor);
  }
}

Performance Comparison

dart
// if-else: O(n) - checks each condition sequentially
if (value == 1) {
  // Check 1
} else if (value == 2) {
  // Check 2
} else if (value == 3) {
  // Check 3
} // Worst case: checks all conditions

// switch-case: O(1) - uses jump table
switch (value) {
  case 1:
    // Direct jump
    break;
  case 2:
    // Direct jump
    break;
  case 3:
    // Direct jump
    break;
} // Constant time lookup

Modern Alternatives (Dart 3.0+)

Switch Expressions (Dart 3.0)

dart
// Old way
String getMessage(Status status) {
  switch (status) {
    case Status.loading:
      return 'Loading...';
    case Status.success:
      return 'Success!';
    case Status.error:
      return 'Error!';
  }
}

// New way (Dart 3.0)
String getMessage(Status status) => switch (status) {
  Status.loading => 'Loading...',
  Status.success => 'Success!',
  Status.error => 'Error!',
};

// In widgets
Widget buildIcon(IconType type) => switch (type) {
  IconType.home => Icon(Icons.home),
  IconType.search => Icon(Icons.search),
  IconType.profile => Icon(Icons.person),
};

Pattern Matching (Dart 3.0)

dart
String describe(dynamic value) => switch (value) {
  int() => 'Integer',
  String() => 'String',
  List() => 'List',
  _ => 'Unknown',
};

// With guards
String categorizeAge(int age) => switch (age) {
  < 13 => 'Child',
  >= 13 && < 20 => 'Teenager',
  >= 20 && < 60 => 'Adult',
  _ => 'Senior',
};

Best Practices

Rule: Use if-else for complex conditions, switch-case for fixed values

✅ Use if-else When:

dart
// Complex conditions
if (user.isLoggedIn && user.age >= 18 && !user.isBanned) {
  // ...
}

// Range checks
if (score >= 90) {
  // ...
} else if (score >= 70) {
  // ...
}

// Null checks
if (user != null && user.name.isNotEmpty) {
  // ...
}

✅ Use switch-case When:

dart
// Fixed enum values
switch (status) {
  case Status.loading:
  case Status.success:
  case Status.error:
}

// String constants
switch (userRole) {
  case 'admin':
  case 'user':
  case 'guest':
}

// Multiple similar values
switch (month) {
  case 1:
  case 2:
  case 12:
    print('Winter');
    break;
}

Common Pitfalls

❌ Forgetting break in switch-case

dart
// Bad - falls through to next case
switch (day) {
  case 'Monday':
    print('Start'); // Falls through!
  case 'Tuesday':
    print('Work'); // Both print!
    break;
}

// Good
switch (day) {
  case 'Monday':
    print('Start');
    break; // ✅
  case 'Tuesday':
    print('Work');
    break;
}

❌ Using switch for ranges

dart
// Bad - doesn't work
switch (age) {
  case >= 18: // ❌ Syntax error
    print('Adult');
}

// Good - use if-else
if (age >= 18) {
  print('Adult');
}

Resources