Accessing InheritedWidget from Provider

131 views
Skip to first unread message

Matt Stagitis

unread,
Mar 17, 2021, 12:43:55 AM3/17/21
to Flutter Development (flutter-dev)
Hi all,

I'm using an InheritedWidget to implement dependency injection in my app. I have a root-level InheritedWidget that holds the dependencies I want to inject throughout.

I'm attempting to access the InheritedWidget's data from a Provider, but I get the following error:

-----
Bad state: Tried to read a provider that threw during the creation of its value.
The exception occurred during the creation of type AuthProvider.
-----

Here is the bit of troublesome code:

-----
class App extends StatelessWidget {
    final Environment _environment;

    App(this._environment);

    @override
    Widget build(BuildContext context) {
        return InjectorWidget(.           // This is my InheritedWidget!
            environment: _environment,
            child: MultiProvider(
                providers: [
                    ChangeNotifierProvider(
                        create: (ctx) => AuthProvider(ctx),
                    ),                    ...
                ],
                child: ...
            ),
        );
    }
}
-----

The problem comes from passing the build context into the provider constructor and then attempting to use it to get access to the InheritedWidget. Is this approach even possible? Or am I missing something?

Thanks!
- Matt

Matt Stagitis

unread,
Mar 17, 2021, 12:58:03 AM3/17/21
to Flutter Development (flutter-dev)
Here is a screenshot of the failure (attached). I've tried using ChangeNotifierProxyProvider as well, but with no success (same error).
Simulator Screen Shot - iPhone 12 Pro Max - 2021-03-16 at 21.55.59.png

Matt Stagitis

unread,
Mar 17, 2021, 1:05:44 AM3/17/21
to Flutter Development (flutter-dev)
Further clarification: This error only occurs when I try to access the InheritedWidget in the constructor of the Provider (which is where I need it). I don't have any issues accessing it from other non-initialization methods.

--
You received this message because you are subscribed to a topic in the Google Groups "Flutter Development (flutter-dev)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/flutter-dev/SHRaWh0Xbsc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to flutter-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/flutter-dev/6467a4ca-05c1-4923-b4fe-6ac72e988b9an%40googlegroups.com.

Suzuki Tomohiro

unread,
Mar 17, 2021, 8:27:08 AM3/17/21
to Matt Stagitis, Flutter Development (flutter-dev)
The error in e screenshot lists several solutions. Do they make sense to you? If not, can you explain they are not applicable here?

You received this message because you are subscribed to the Google Groups "Flutter Development (flutter-dev)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/flutter-dev/CAO5UskRe5%3DGvBWC2SE8835BH9EKdVJi6R3vCzhi%3DZCJHjwkPnQ%40mail.gmail.com.

Matt Stagitis

unread,
Mar 17, 2021, 12:42:21 PM3/17/21
to Flutter Development (flutter-dev)
Thanks for the response! You're right, the error does list a few potential solutions.

1. pass 'listen: false' to 'Provider.of'
I am not using Provider.of(). I am attempting to access my InheritedWidget from the Provider using InjectorWidget.of().

2. use a life-cycle that handles updates (like didChangeDependencies)
The Provider class doesn't implement didChangeDependencies (as far as I know).

3. use a Provider that handles updates (like ProxyProvider)
My understanding of ProxyProvider is to pass one provider into another, but I don't need to do that here. I simply want to pass the BuildContext into the Provider's constructor.

Thanks ahead of time!

Suzuki Tomohiro

unread,
Mar 17, 2021, 12:51:38 PM3/17/21
to Matt Stagitis, Flutter Development (flutter-dev)
Nice explanation. Do you want to share the code of the constructor of AuthProvider?

Matt Stagitis

unread,
Mar 17, 2021, 1:56:35 PM3/17/21
to Flutter Development (flutter-dev)
Sure, here you go:

-----
class AuthProvider extends ChangeNotifier {
    final Data myData;

    AuthProvider(BuildContext context) {
        final InjectorWidget injectorWidget = InjectorWidget.of(context);
        // Use injectorWidget
    }
}
-----

I *think* I might know what my issue is. Is the BuildContext available when I construct my AuthProvider (in code above)? Or are the class instances all constructed first, with build() following?

- Matt

Matt Stagitis

unread,
Mar 17, 2021, 2:44:28 PM3/17/21
to Flutter Development (flutter-dev)
If my AuthProvider was a StatefulWidget, I could just call didChangeDependencies() and use the context to access the InjectorWidget there. But my AuthProvider is a ChangeNotifier, which doesn't have that...

Suzuki Tomohiro

unread,
Mar 17, 2021, 7:34:13 PM3/17/21
to Matt Stagitis, Flutter Development (flutter-dev)

Matt Stagitis

unread,
Mar 17, 2021, 8:07:27 PM3/17/21
to Suzuki Tomohiro, Flutter Development (flutter-dev)
No, InjectorWidget is a class that I wrote that extends InheritedWidget.

Suzuki Tomohiro

unread,
Mar 17, 2021, 8:15:40 PM3/17/21
to Matt Stagitis, Flutter Development (flutter-dev)
Good. What’s the implementation of InjectorWidget.of() ?

Matt Stagitis

unread,
Mar 17, 2021, 9:23:20 PM3/17/21
to Suzuki Tomohiro, Flutter Development (flutter-dev)
In the InjectorWidget:

-----
static InjectorWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<InjectorWidget>();
}
-----

Matt Stagitis

unread,
Mar 17, 2021, 9:26:46 PM3/17/21
to Suzuki Tomohiro, Flutter Development (flutter-dev)
After looking at the dependencies_flutter plugin, I think I will have the same issue. I will not be able to call

final injector = InjectorWidget.of(context);

in the Provider's constructor. This is exactly what I'm trying to do now.

- Matt

Suzuki Tomohiro

unread,
Mar 17, 2021, 11:10:09 PM3/17/21
to Matt Stagitis, Flutter Development (flutter-dev)
I got the meaning of the error.


This method should not be called from widget constructors

You are calling the method from ChangeNotifierProvider’s constructor. ChangeNotifierProvider is a widget. (Note that AuthProvider is not a widget)

Does this explanation make sense?
(I don’t know the solution)
Reply all
Reply to author
Forward
0 new messages