Reputation: 1969
I'm trying to figure out a good way of architecturing a Flutter app. I have several pages, which can navigate to other pages. Data modified by one page, might be used by other pages and needs to be updated. I recently started using the Provider package. I let each page have a model which implements ChangeNotifier and set a ChangeNotifierProvider above the MaterialApp. Now to update the data for other pages, i have to get the other page's model and call an update method on it. It's quite messy. I use Firestore, so i could listen to database changes, but i want to avoid too much magic. Also, sometimes it makes sense to just send data from one page to another, without using a network call, or pass data back in the Navigator.pop method. I find it hard to make good choices in how to solve this. I should probably look at a more refined architecture like redux or mobx. Or just go for a vanilla solution and use lot's of callbacks for all the various events. Those big'ol models per page, seems a bit bit bloated and messy after a while. Do anyone have a similar experience in Flutter how to architect these things? Confused
Upvotes: 0
Views: 1278
Reputation: 900
Using provider to apply the BLoC
pattern and combining it with RxDart is a way of solving this.
You could, for example, create an AppBloc
:
class AppBloc {
StreamController<UserInputState> _userInputController =
BehaviorSubject<UserInputState>.seeded(UserInputState('NOTHING'));
StreamSink<UserInputState> get userInputSink => _userInputController.sink;
Observable<UserInputState> get userInputObs => Observable(_userInputController.stream);
AppBloc();
}
class UserInputState {
final String input;
const UserInputState(this.input);
}
On a page you could pass data through it:
final appBloc = Provider.of<AppBloc>(context);
appBloc.userInputSink.add(UserInputState("input"));
and another page can listen to data:
final appBloc = Provider.of<AppBloc>(context);
appBloc.userInputObs.
.where((state) => state.input == "input")
.listen((state) => /* do something */);
I've simplified it here, but this can be a very robust way of handling data in a reactive way.
And the beauty is that you can bind the Observable
to a StreamBuilder (part of Flutter) to make the UI reactive too!
Upvotes: 3
Reputation: 977
Using Provider (or any library that implements BloC pattern) and a Repository Pattern should work to move/store data locally. Basically each Bloc/Provider gets an instance of the repository and read/write values to it. Because the repository instance is the same always, you will have all yout data updated.
Also, you can use a local database like SQLite (with the sqflite package) or Hive that is a pure NoSQL database.
I personally don't like Redux, but mobx is a really good option.
Upvotes: 1