0

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;
RagAnt
  • 1,064
  • 2
  • 17
  • 35

1 Answers1

4

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); 
  }

}
Josteve
  • 11,459
  • 1
  • 23
  • 35
  • Great answer . Even for copyWith method , we need some extra coding but just in the beginning only . So OK . – RagAnt Jan 18 '22 at 09:06
  • What is the difference and advantages of state notifier VS change notifier ? – RagAnt Jan 18 '22 at 09:06
  • 1
    The main difference between them is that StateNotifier will promote an immutable architecture. This has the tendency to make code more maintainable on the long run. – Josteve Jan 18 '22 at 09:10
  • One question please. So there is no direct way (by modifying a variable, like GetX) to refresh the state in both Change and State notifiers without calling notify listeners or reinitialising the state model ? Right ? – RagAnt Jan 18 '22 at 09:56
  • 1
    By "refresh" do you mean setting it to the initial value? – Josteve Jan 18 '22 at 09:59
  • Sorry for bad English . Some thing like , a Text(counter.age) widget have to display new value (24) directly when only ref.read(provider.notifier).age = 24 executed ? – RagAnt Jan 18 '22 at 10:09
  • Hi, is there a possibility you could help on my issue where i would like to use riverpod. – LearnFlutter Feb 04 '22 at 14:51
  • https://stackoverflow.com/questions/70980002/flutter-use-variable-created-inside-future-builder-outside-of-the-build-method – LearnFlutter Feb 04 '22 at 14:51