Is there a way I could refactor these similar functions in dart?

Issue

I’m trying to set the state of the variables using provider state management in Flutter, so when I call the provider in my build, it’s going to change the state of the booleans in my provider class.

The problem now is most of the function in the provider are doing basically the same thing, since they are just changing the value of the boolean to the opposite.

I’ve been looking for a way to make the code shorter since the functions are doing basically the same thing. I’ve been wrapping my head around the whole thing but I can’t come up with anything, and having this spaghetti mess of code hurts my eyes:

class AlarmState extends ChangeNotifier {
  var hour = 0;
  var min = 0;
  bool isWednesday = false;
  bool isMonday = false;
  bool isTuesday = false;
  bool isThursday = false;
  bool isFriday = false;
  bool isSaturday = false;
  bool isSunday = false;
  bool alarmRing = false;
  bool vibrate = false;
  bool snooze = false;
  List<AlarmObject> alarmList = [];
  bool isAlarmOn = true;

  void handleChangeHour(int index) {
    hour = index;
    notifyListeners();
  }

  void handleChangeMin(int index) {
    min = index;
    notifyListeners();
  }

  void changeMonday() {
    isMonday = !isMonday;
    notifyListeners();
  }

  void changeTuesday() {
    isTuesday = !isTuesday;
    notifyListeners();
  }

  void changeWednesday() {
    isWednesday = !isWednesday;
    notifyListeners();
  }

  void changeThursday() {
    isThursday = !isThursday;
    notifyListeners();
  }

  void changeFriday() {
    isFriday = !isFriday;
    notifyListeners();
  }

  void changeSaturday() {
    isSaturday = !isSaturday;
    notifyListeners();
  }

  void changeSunday() {
    isSunday = !isSunday;
    notifyListeners();
  }

  void handleAlarmRing(value) {
    alarmRing = value;
    notifyListeners();
  }

  void handleSnooze(value) {
    snooze = value;
    notifyListeners();
  }

  void handleVibrate(value) {
    vibrate = value;
    notifyListeners();
  }

  void handleIsAlarmOn(bool value) {
    isAlarmOn = value;
    print(isAlarmOn);
    notifyListeners();
  }
}

Solution

I recommend using an enum Weekday to represent the days, and using a Set<Weekday> to keep track of which days are active. Then, using a single function with optional named parameters to update the AlarmState.

The end result may look something like this:

enum Weekday {
  monday,
  tuesday,
  wednesday,
  thursday,
  friday,
  saturday,
  sunday,
}

class AlarmState extends ChangeNotifier {
  var hour = 0;
  var min = 0;
  Set<Weekday> activeDays = Set();
  bool alarmRing = false;
  bool vibrate = false;
  bool snooze = false;
  List<AlarmObject> alarmList = [];
  bool isAlarmOn = true;

  void update({
    int? hour,
    int? min,
    Set<Weekday>? activeDays,
    bool? alarmRing,
    bool? vibrate,
    bool? snooze,
    bool? isAlarmOn,
  }) {
    this.hour = hour ?? this.hour;
    this.min = min ?? this.min;
    this.activeDays = activeDays ?? this.activeDays;
    this.alarmRing = alarmRing ?? this.alarmRing;
    this.vibrate = vibrate ?? this.vibrate;
    this.snooze = snooze ?? this.snooze;
    this.isAlarmOn = isAlarmOn ?? this.isAlarmOn;
    notifyListeners();
  }
}

So then, for a few examples of updating your alarm, it should look something like this:

final alarmState = AlarmState();

// Add monday, wednesday and friday
alarmState.update(
    activeDays: alarmState.activeDays..addAll([
        Weekday.monday,
        Weekday.wednesday,
        Weekday.friday,
    ]),
);

// Remove monday
alarmState.update(
    activeDays: alarmState.activeDays..remove(Weekday.monday),
);

// Update hour and minute
alarmState.update(
    hour: 12,
    min: 30,
);

// Turn off the alarm
alarmState.update(
    isAlarmOn: false,
);

// Check whether the alarm should go off on monday
final isActiveOnMonday = alarmState.activeDays.contains(Weekday.monday);

Answered By – Michael Horn

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *