Search code examples
flutterdartflutter-provider

How to create multiple instance of same provider in flutter


I'm using a provider to fetch the data and notify the listeners as follows:

class CategoryProvider with ChangeNotifier {

  Future<void> getData() async {
     ......
     ......
     notifyListeners();
   }

}

My CategoryListView widget is listening to this provider as follows:

Widget build(BuildContext context) {
    var collectionData = Provider.of<CategoryProvider>(context);
}

I'm pushing new instance of CategoryListView as follows:

Navigator.of(context).pushNamed(CategoryListView.routeName);

I'm pushing new instances of CategoryListView from CategoryListView widget itself. It works fine on pushing new instances, but on navigating back, all the CategoryListView widgets are showing the data of the latest CategoryListView widget pushed into the stack as it's listening to the same provider. How can I create new instance of provider and associate it to a widget instance? Is there a better approach to handle this?


Solution

  • I have solved it and I'm posting the solution so that it may help someone.

    The new instance of provider is declared in CategoryListView class follows:

      final CategoryProvider collectionData = CategoryProvider();
    

    Similarly, instead of passing associated data for CategoryListView as navigator arguments, I passed it as constructor values so that those values will be accessible in initState() function.

    Hence pushing of a new instance of CategoryListView is changed from

    Navigator.of(context).pushNamed(CategoryListView.routeName);
    

    to

    Navigator.push(context, MaterialPageRoute(builder: (context) => 
    CategoryPage(constructorValue) ));
    

    On initState() function, set the necessary values to the provider and make the necessary function calls.

     collectionData.catalogueId = widget.catalogueId;
     collectionData.loadNextPage();
    

    On Widget build(BuildContext context), listening to the provider is changed from

         Widget build(BuildContext context) {
        var collectionData = Provider.of<CategoryProvider>(context);
    }
    

    to

    Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Color(0xff04063E),
            title: Text(widget.catalogueName != null ? widget.catalogueName : ""),
            
          ),
          body: ChangeNotifierProvider.value(
            value: collectionData,
            child: Consumer<CategoryProvider>(builder: (_, ctl, __) {
              return _buildUI(collectionData);
            }),
          ),
        );
      }
    

    Where _buildUI(collectionData) is a function which builds the UI from the provide instance collectionData.

    Also, dispose the provider instance on dispose:

    @override
      void dispose() {
        collectionData.dispose();
        super.dispose();
      }