Ошибка Future provider Error: Could not find the correct Provider> above this ListStarts Widget

Впервые использую provider и не знаю как исправить эту ошибку. У меня есть bottom nav bar, в котором я перехожу на другие страницы и когда я перехожу на страницу, где использую future provide то выдает эту ошибку:

Error: Could not find the correct Provider<List> above this ListStarts Widget

This happens because you used a BuildContext that does not include the provider of your choice. There are a few common scenarios:

  • You added a new provider in your main.dart and performed a hot-reload. To fix, perform a hot-restart.

  • The provider you are trying to read is in a different route.

    Providers are "scoped". So if you insert of provider inside a route, then other routes will not be able to access that provider.

  • You used a BuildContext that is an ancestor of the provider you are trying to read.

    Make sure that ListStarts is under your MultiProvider/Provider<List>. This usually happens when you are creating a provider and trying to read it immediately.

Класс с provide:

class MyStartsProvider {
  final String _dataPath = "assets/MyStarts.json";
  late List<MyStart> myStarts;

  Future<String> loadAsset() async {
    return await Future.delayed(Duration(seconds: 1), () async {
      return await rootBundle.loadString(_dataPath);
    });
  }

  Future<List<MyStart>> loadMyStart() async {
    var dataString = await loadAsset();
    Map<String, dynamic> jsonMyStartData = jsonDecode(dataString);
    myStarts = MyStartList.fromJson(jsonMyStartData['MyStarts']).myStarts;
    print('done loading starts');
    return myStarts;
  }
}

myApp:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //debugShowCheckedModeBanner: false,
      home: MultiProvider(providers: [
        FutureProvider(
          create: (BuildContext context) async =>
              MyStartsProvider().loadMyStart(),
          initialData: [],
        ),
      ], child: BottomNavigator()),
    );
  }
}

Где и как я использую provide:

class ListStarts extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    List<MyStart> starts = Provider.of<List<MyStart>>(context);
    return ListView.separated(
        padding: EdgeInsets.only(top: 10),
        separatorBuilder: (context, int index) => Divider(
              height: 56,
            ),
        itemCount: 3,
        itemBuilder: (context, index) {
          return Container(
            width: 327,
            height: 343,
            color: Colors.red,
            child: Column(
    ....


Ответы (1 шт):

Автор решения: steind.VY

Проблема решена следующими правками:

  • Изменение типа результата метода loadMyStart на Future<MyStartList>. Класс MyStartList объявлен так:

    class MyStartList {
      final List<MyStart> items;
      MyStartList(this.items);
    
      MyStartList.fromJson(List<dynamic> myStartsJson)
          : this.items = myStartsJson.map((myStart) => MyStart.fromJson(myStart)).toList();
    }
    
  • Соответственно изменен и тип свойства myStarts провайдера

    class MyStartsProvider {
      final String _dataPath = "assets/MyStarts.json";
      late MyStartList myStarts;
      /*....*/
    }
    
  • Изменение типа провайдера в MultiProvider

    MaterialApp(
      home: MultiProvider(providers: [
        FutureProvider<MyStartList>(
          create: (BuildContext context) async => MyStartsProvider().loadMyStart(),
          initialData: MyStartList([]),
        ),
      ],
      /*....*/
    )
    
  • Использование Consumer<MyStartList> вместо Provider.of<List<MyStart>>

    class ListStarts extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Consumer<MyStartList>(
          builder: (context, startList, child) =>  ListView.separated(/*....*/)
        ),
      }
    }
    
  • Соотв. изменение выражения чтения значения в виджете вложенном в консьюмер

    Text('${startList.items[index].title}', /*....*/)
    
→ Ссылка