Flutter: In RiverPod , how to alter state model's variables directly?

Issue

I am currently learning River Pod and also new to flutter.

When setting new state in StateNotifer , I need to create a new model and replace the state

But directly changing is not working

class CounterModel  {
  CounterModel(this.count, this.age);
    int count;
    int age;
}

class CounterNotifier extends StateNotifier<CounterModel> {
  CounterNotifier() : super(_initialValue);
  static CounterModel  _initialValue = CounterModel(0,18);

  void increment() {
  //  state.count = state.count + 1; // not working, but need like this !
    state = CounterModel(state.count + 1, state.age); // working 
  }

}

In the above code , when I trying to change the count variable directly like, state.count = state.count + 1 , nothing changed

But when reinitialising the state by creating a new model like state = CounterModel(state.count + 1, state.age)

Its seems to be state model variables are immutable and needs to be recreated on every alteration !

My question is , what if the CounterModel have 50 variables , then I have to do something like

state = CounterModel (var1,var2,......,var49,var50) ;

So , is it possible to directly change the variables like

state.var1 = new_value1;
state.var2 = new_value2;
....
state.var50 = new_value50;

Solution

You have to always reassign the state in StateNotifier for Consumers to see the changes hence, state.var1 = new_value1; can’t work with StateNotifier

If You’re very keen about that syntax, use ChangeNotifier since it allows you change individual properties of the class but you must call notifyListeners

Like so:

class CounterNotifier extends StateNotifier {
  static CounterModel value = CounterModel(0,18);

  void increment() {
    value.count = value.count + 1;
    notifyListeners();
  }
}

If You want to stick with StateNotifier and don’t want to write boilerplate code, create a copyWith method on the model.

Like so:

class CounterModel  {
  CounterModel(this.count, this.age);
  int count;
  int age;

  CounterModel copyWith({int? count, int? age}){
     return CounterModel(
       count ?? this.count,
       age ?? this.age
     );
  }
}

Then you can keep reassigning with it like so:

class CounterNotifier extends StateNotifier<CounterModel> {
  CounterNotifier() : super(_initialValue);
  static CounterModel  _initialValue = CounterModel(0,18);

  void increment() {
    state = state.copyWith(count: state.count + 1); 
  }

}

Answered By – Josteve

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

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