Ali Hazem
Ali Hazem

Reputation: 89

I try using Provider read methods to add desired stuff but nothing works

I have 2 models extending ChangeNotifier called Tabs and Views. Tabs for tabs parameter of TabBar an Views for TabBarView.

models:

Tabs.dart

 class Tabs with ChangeNotifier {
  final List<Widget> _tabs = [Text('Today')];
  List<Widget> get tabs => _tabs;

  void addTabs(String text) {
    _tabs.add(Tab(text: text));
    notifyListeners();
  }

  void removetabs(String text) {
    _tabs.remove(Tab(text: text));
    notifyListeners();
  }
}

Views.dart

class Views with ChangeNotifier {
final List<Widget> _views = [Container(color: Colors.red, height: 100, width: 100,)];
  List<Widget> get views => _views;
  void addView(Widget widget) {
    _views.add(widget);
    notifyListeners();
  }
}

main.dart

class _MyAppState extends State<MyApp> {
@override
  Widget build(BuildContext context) {
    return MultiProvider(providers: [
    ChangeNotifierProvider<Tabs>(create: (_) => Tabs()),
        ChangeNotifierProvider<Views>(create: (_) => Views()),
  ],
  builder:(context, child)=> MaterialApp(.......);

So for both TabBar and TabBarView I watch or listen to the List tabs and views model variables and that works perfectly fine as I tried adding hard coded widgets to these 2 variables. However, Provider read method doesn't work when I try adding a tab or view. final tabs = Tabs().tabs; final views = Views().views;

AppBar(bottom: tabs.isNotEmpty
              ? TabBar(
                  indicatorColor: Colors.white,
                  tabs: context.watch<Tabs>().tabs,
                )
              : null),

body: tabs.isNotEmpty
          ? TabBarView(children: context.watch<Views>().views)
          : appLogo,

adding tabs and views

So in my app I first query firebase docs and if there isn't any doc I want to add one with the date 'Today' and then add to the tabs and views model variable that I created but nothing get added to these 2 lists.

Future addTabsViews() async {
  try{
  QuerySnapshot<Map<String, dynamic>> query = await todosRef.limit(1).get(const GetOptions(source: Source.server));

  if (query.docs.isEmpty) {
    Map<String, dynamic> todayDoc = {
      'todo': null,
      'subTask': null,
      'isChecked': null,
      'date': 'Today'
    };
    await todosRef.add(todayDoc);
    context.read<Tabs>().addTabs(todayDoc['date']);
    context.read<Views>().addView(Container());
    print(tabs);
    print(views);
  } } on FirebaseException catch (e){
    print(e.toString());
  }
}

I call this future in the initState; Been stuck in this error for days and can't fix it until now.

Upvotes: 0

Views: 32

Answers (1)

Jacob Welin
Jacob Welin

Reputation: 191

When you create your tabs and views that you reference like this, you are creating new objects and not referencing the same that you use in your provider.

final tabs = Tabs().tabs;

final views = Views().views;

To get the Tabs instance from the provider and listen to any updates you have to get it like this e.g.:

var tabs = Provider.of(context).tabs;

You can now use tabs from the provider and they will update when you notifyListeners();

Widget build(BuildContext context) {
    var tabs = Provider.of<Tabs>(context).tabs;
    var views = Provider.of<Views>(context).views;
    
    return Scaffold(
      appBar: AppBar(bottom: tabs.isNotEmpty ? TabBar(tabs: tabs) : null),
      body: tabs.isNotEmpty ? TabBarView(children: views) : FlutterLogo(),
    );
}

Upvotes: 1

Related Questions