Застрял с интеграцией провайдера с sqflite во флаттер-приложении

Я пытаюсь реализовать шаблон поставщика, но мне сложно интегрировать его с базой данных sqflite. Класс ChangeNotifier получает список строк из базы данных и затем отображает его с помощью ListView. Я полагаю, проблема в том, что когда ListView строит виджет, класс ChangeNotifier еще не инициализировал список, поэтому приложение вылетает. Как я могу это решить?

class FavouritesProvider with ChangeNotifier {
 
  List<String> _favourites;
 
  List<String> get favourites => [..._favourites];
 
  FavouritesProvider() {
    fetchAndSetFav();
  }
 
  Future<void> fetchAndSetFav() async {
    final data = await DBHelper.instance.getFavourites();
    _favourites = data;
  }
 
}
 
@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ChangeNotifierProvider(
      create: (_) => FavouritesProvider(),
      child: Container (
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
            colors: [
              Colors.blue[200],
              Colors.blue
            ],
            stops: [0.0,1]
          )
        ),
        child: Consumer<FavouritesProvider>(
          builder: (context, favouritesProvider, child) => ListView.builder (
                itemCount: favouritesProvider.favourites.length,
                itemBuilder: (context, index) {
                  return Container(
                    padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
                    width: double.maxFinite,
                    child: FavouritePositionWidget(key: new Key(index.toString()), streetName: favouritesProvider.favourites[index])
                  );
                },
          )
        )
      )
      )
    );
  }

Но я получаю эту ошибку

The following NoSuchMethodError was thrown building Consumer<FavouritesProvider>(dirty, dependencies: [_InheritedProviderScope<FavouritesProvider>]):
The getter 'iterator' was called on null.
Receiver: null
Tried calling: iterator

person Niccolò Simoni    schedule 17.12.2020    source источник


Ответы (1)


Я думаю, проблема в том, что вы не можете одновременно создавать и использовать поставщика в одном методе сборки. Распространенной практикой является создание провайдеров на самом верху дерева.

Из примера поставщика:

void main() {
  runApp(
    /// Providers are above [MyApp] instead of inside it, so that tests
    /// can use [MyApp] while mocking the providers
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Counter()),
      ],
      child: const MyApp(),
    ),
  );
}
person MickaelHrndz    schedule 17.12.2020