0

I have these two calls to makeChild(...) in a widget. On top of the tree there's a ChangeNotifierProvider, and inside the makeChild function I'm accessing the data model via Provider.of<...>(context).

The problem is that inside the widget generated by the second call it works fine, but in the first one (the call to showModalBottomSheet) it throws an error saying that the correct provider couldn't be found above this widget.

import 'package:flutter/material.dart';


class PuzzleBox extends StatelessWidget {
  const PuzzleBox({
    Key? key,
    required this.makeChild,
  }) : super(key: key);

  final Function makeChild;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: GestureDetector(
        onTap: () {
          showModalBottomSheet(
              context: context,
              builder: (context) => 
                  // THIS DOESN'T HAVE THE RIGHT CONTEXT (PROVIDER NOT FOUND)
                    makeChild(showUI: true),
                  );
        },
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
           
            const Divider(height: 24),
            Center(
                child: IgnorePointer(
                  // THIS RENDERS FINE AND HAS THE CORRECT CONTEXT
                    child: FittedBox(child: makeChild(showUI: false)))),
          ],
        ),
      ),
    );
  }
}

In other words, the function directly inside the widget tree generates a widget that can access my Provider, but the same function that's in the showModalBottomSheet generates one that can't. Why?

darekm
  • 285
  • 1
  • 12
  • 1
    Does this answer your question? [How to access Provided (Provider.of()) value inside showModalBottomSheet?](https://stackoverflow.com/questions/57547784/how-to-access-provided-provider-of-value-inside-showmodalbottomsheet) – Adelina Oct 13 '21 at 18:02

1 Answers1

-1

To avoid complicating code and passing parameters, you can use the mobx package:

https://pub.dev/packages/mobx

https://pub.dev/packages/flutter_mobx

https://pub.dev/packages/mobx_codegen

It doesn't require context, so this will ease your code a lot and will allow you to access the provider from everywhere.

All you have to do is to create your provider class using the correct annotation: @observable, @computed and @action

And generate the part of the dart file using build_runner as you'll see in the documentation.

After this, you'll have to declare your provider globally and import it to use it where you want.

final myProvider = MyClassProvider();

// Anywhereby importing the file where is myProvider

myProvider.value = 'x';
Marius Atasiei
  • 275
  • 1
  • 10
  • This has nothing to do with the question – Nico Spencer Oct 14 '21 at 00:29
  • MobX is a Provider alternative that can be used in showModalBottomSheet, showDialog, etc... since it doesn't require context – Marius Atasiei Oct 14 '21 at 06:07
  • That is not correct. MobX is reactive state-management. Provider is an `InheritedWidget` that gives the widget tree access to instances. These are not the same and therefore not an alternative. Instead of creating a singleton as you're suggesting, you could use Provider to provide a MobX store. My company shifted away from MobX as we saw too many hard to track down bugs. – Nico Spencer Oct 14 '21 at 06:17
  • If you declare an instance of your class provider, globally, you will be able to use it wherever you want. https://flutter.dev/docs/development/data-and-backend/state-mgmt/options As you see here on docs, you have a list of state management, where are Provider and MobX, also, so we can say that MobX can be an alternative for Provider. – Marius Atasiei Oct 14 '21 at 09:42