0

I need to access a value of a provider but I can't pass a context so I created created a global navigatorKey like this:

final rootNavigatorKey = GlobalKey<NavigatorState>();

and set it in my app.

Now I have a function that should listen to my provider but it doesn't work:

  String get tr {
    Locale currentLocale = Provider.of<LocaleProvider>(
      rootNavigatorKey.currentContext!,
      listen: true,
    ).currentLocale;

    return translationsKeys[currentLocale.languageCode]![this]!;
  }

Like I said, this is not properly listening because when calling notifyListeners inside the provider, nothing happens, the visible data is not updated. But when scrolling down and up again, the data is updated. Same when popping the view, the data is updated. Only the currently visible data is not updated.

  void setLocale(Locale locale) {
    currentLocale = locale;
    notifyListeners();
  }

However, when passing the actual context it is working as expected:

  String tr2(BuildContext context) {
    Locale currentLocale = Provider.of<LocaleProvider>(
      context,
      listen: true,
    ).currentLocale;

    return translationsKeys[currentLocale.languageCode]![this]!;
  }

Is there any way I can fix this so I dont need to pass the context?

I know that Providers are scoped. So I put the provider above me app inside a MultiAppProvider and also tried a solution mentioned here with the my goRouter:

final rootNavigatorKey = GlobalKey<NavigatorState>();

class AppRouter {
  static final _shellNavigatorKey = GlobalKey<NavigatorState>();

  static final router = GoRouter(
    initialLocation: IntroView.path,
    debugLogDiagnostics: true,
    navigatorKey: rootNavigatorKey,
    routes: [
      ShellRoute(
        navigatorKey: _shellNavigatorKey,
        pageBuilder: (context, state, child) {
          return NoTransitionPage(
            child: ScaffoldView(
              child: child,
            ),
          );
        },
        routes: [
          GoRoute(
            name: ProjectsView.name,
            path: '/projects',
            parentNavigatorKey: _shellNavigatorKey,
            pageBuilder: (context, state) {
              return const FadePageTransition(
                page: ProjectsView(),
              );
            },
            routes: [
              GoRoute(
                parentNavigatorKey: rootNavigatorKey,
                path: ':projectTitle',
                pageBuilder: (context, state) {
                  final localeProvider = Provider.of<LocaleProvider>(context);
                  return FadePageTransition(
                    page: ChangeNotifierProvider.value(
                      value: localeProvider,
                      child: ProjectDetailScaffold(
                        project: Projects.values.byName(
                          state.params['projectTitle']!,
                        ),
                      ),
                    ),
                  );
                },
              ),
            ],
          ),

But when calling setLocale like above I get this error:

The following assertion was thrown building Builder(dirty, dependencies: [_InheritedProviderScope<LocaleProvider?>]): Assertion failed: file:///Users/christiankonnerth/.pub-cache/hosted/pub.dev/go_router-6.0.1/lib/src/builder.dart:136:14 builder.dart:136 _routeMatchLookUp.isEmpty is not true

Chris
  • 1,828
  • 6
  • 40
  • 108

1 Answers1

0

When using [Flutter's Provider]1 package, you might encounter issues with the context not listening when using the rootNavigatorState. This is a known issue and can happen when there are multiple nested navigators in your app.

To solve this issue, you can try using a different approach to access the context within your Provider. Instead of using context directly, you can use Builder widget to create a new context that is scoped to the specific widget subtree where you need to access the Provider.

By using the Builder widget, you ensure that the context used to access the Provider is scoped correctly and listens to changes.

If the issue persists, it's recommended to provide more specific details and code snippets so that the problem can be better understood and addressed.

  • could you give me an example for this? – Chris May 21 '23 at 09:04
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 21 '23 at 11:53