Access Providers from Dialogs for Flutter hooks

1.1k views Asked by At

I am new to Flutter hooks and riverpod

Basically I have a provider that stores the list of books in a book shelf.

class BookList extends StateNotifier<List<BookModel>> {
  BookList() : super([]);

  void setBookList(List<BookModel> bookList) =>
     {state = bookList};
}

final bookListProvider = StateNotifierProvider<BookList>((_) => BookList());

Then I have a page which display the books and a create button which will shows the create a new book dialog:

class BookShelfPage extends HookWidget {
  @override
  Widget build(BuildContext context) {
      final bookList = useProvider(bookListProvider.state);
      
      useEffect(() {
        //API to get list of books
        context.read(bookListProvider).setBookList(//data from API);
      },[]);

      final Function() onCreateBookButtonClicked = () {      
        showDialog(
          context: context,
          builder: (context) => ProviderScope(
            child: (new BookCreateDialog())));
      };


      //Data is available for this
      print("book list length 1: " + bookList.length.toString()); 
  }

However, I am unable to access the provider values in the dialog:

class BookCreateDialog extends HookWidget {
   @override
   Widget build(BuildContext context) {
      final bookList = useProvider(bookListProvider.state);
      
      //Data is not available for this
      print("book list length 2: " + bookList.length.toString()); 
   }
}

Things to note:

  1. I have a ProviderScope wrapping my application.
  2. I have no problems persist or access the providers across different PAGES or any child widget that resides on the PAGES but I am not able to access the provider values from dialogs.
  3. Of course, I can pass the providers' values as parameters to the dialogs but I would like to know if there is any way that I can avoid this as I got a lot values to get from providers.

May I know how to fix this? Much thanks!

1

There are 1 answers

0
Alex Hartford On

You only want to use ProviderScope in two cases. The first is wrapping your app as you mentioned. The other case is when using ScopedProvider.

What you're essentially doing here:

builder: (context) => ProviderScope(child: BookCreateDialog());

is creating a new scope where the value of your StateNotifierProvider is not available (as that value lies within the ProviderScope at the root of your app).

Remove that ProviderScope and you should get the results you are expecting.