flutterscoped-model

How to retain data while using ScopedModel in Flutter?


I am using ScopedModel to fetch some data from a Firebase database.

I am fetching a list of events.

  1. I fetch the events from the endpoint inside the Model;
  2. I store the events into a List<Event> inside the model;
  3. I use that list to build my ListView.
mixin EventModel on Model {
    List<Event> _events = [];

    Future<http.Response> fetchEvents() async {
          http.Response response = await http.get(//Url);

            final List<Event> fetchedEvents = [];

            ... // decode response data into fetchedEvents

            // Add the loaded data to my List
            _events = fetchedEvents;
            notifyListeners();

            ...
      }

}

So, when opening the EventsPage the first thing I do is to fetch the data in initState().

class _EventPageState extends State<EventPage> {
  @override
  void initState() {
    super.initState();
      widget.model.fetchEvents();
    }
  }
}

After fetching the network data, my List inside my app has the network data so I can use it to build my ListView.

EventsPage.dart

Widget _buildListView(MainModel model) {
    return Center(
      child: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return ItemEventBig(model.events[index], index);
        },
        itemCount: model.events.length,
      ),
    );
  }

My problem is that, if I navigate to another page and then come back to EventsPage, initState() will be called again, so fetchEvents. Making the app reload all the events list again.

I would like to retain the downloaded data while my app is alive, so If the user go and come back to EventsPage the data will not be lost.

I was used to do it in Android using ViewModel, how to do it in Flutter?

I want to keep using ScopedModel to do my State Management in Flutter.

Possible Solution

I thought that a solution would be to store the events in a List<Event> as I am doing. Then, when calling fetchEvents() I could first check if my List<Event> is not null if so, I don't need to call it again because data was already loaded.

This seems a bad solution for me, especially when I have multiple pages fetching the data. Suppose I load the first one, when I go to the second one it will assume the data was already loaded because List<Event> is non null and it will not load again.


Solution

  • See Flutter Documentation - https://api.flutter.dev/flutter/widgets/AutomaticKeepAliveClientMixin-mixin.html

    class _EventPageState extends State<EventPage> 
         with AutomaticKeepAliveClientMixin<EventPage> {
      @override
      void initState() {
        super.initState();
          widget.model.fetchEvents();
        }
      }
      @override
      // TODO: implement wantKeepAlive
      bool get wantKeepAlive => true;
    }