Flutter Error - Dialog Not Displayed Due to Missing MaterialApp Ancestor

96 views Asked by At

I'm encountering an error related to the absence of a MaterialApp ancestor in my Flutter application. My app's structure includes a MultiProvider and a ModularApp setup, but I'm still receiving an error about missing MaterialApp.

Here's a simplified version of my code structure:

// main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  runApp(
    ModularApp(
      module: AppModule(),
      child: const AppWidget(),
    ),
  );
}

// AppModule.dart
class AppModule extends Module {
  // ... (module configuration)
}

// AppWidget.dart
class AppWidget extends StatelessWidget {
  const AppWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    LocalJsonLocalization.delegate.directories = ['lib/assets/i18n'];

    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => ChatNotificationService(),
        ),
        ChangeNotifierProvider(
          create: (_) => AuthUseCase(),
        ),
        ChangeNotifierProvider(
          create: (context) => AuthViewModel(
            AuthUseCase(),
            context,
          ),
        ),
      ],
      child: MaterialApp.router(
        theme: ThemeData(
            fontFamily: 'Lato',
            colorScheme: ColorScheme.fromSwatch().copyWith(
              primary: const Color(0xFF0096C7),
              secondary: Colors.orange.shade700,
              tertiary: Colors.white,
              outline: Colors.grey,
            )),
        debugShowCheckedModeBanner: false,
        scrollBehavior: AppScrollBehavior(),
        title: 'app_name'.i18n(),
        localizationsDelegates: [
          GlobalMaterialLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          LocalJsonLocalization.delegate
        ],
        supportedLocales: const [
          Locale('pt', 'BR'),
          Locale('en', 'US'),
        ],
        routerConfig: Modular.routerConfig,
      ),
    );
  }
}

// AuthViewModel.dart
class AuthViewModel extends ChangeNotifier {
  final AuthUseCase _authUseCase;
  final BuildContext context;

  AuthViewModel(this._authUseCase, this.context);

  Future<void> login(String email, String password) async {
    try {
      _isLoading = true;
      notifyListeners();

      final errorMessage = await _authUseCase.login(email, password);

      if (errorMessage != null) {
        _showErrorDialog(errorMessage);
      } else {
        Modular.to.navigate('/home/');
      }
    } on AuthException catch (error) {
      _handleAuthException(error);
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  void _showErrorDialog(String msg) {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text('error_occurred'.i18n()),
        content: Text(msg),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: Text('close'.i18n()),
          ),
        ],
      ),
    );
  }
}

// LoginScreen.dart
Future<void> _submit() async {
  final isValid = _formKey.currentState?.validate() ?? false;

  if (!isValid) {
    return;
  }

  _formKey.currentState?.save();

  AuthViewModel authViewModel =
      Provider.of<AuthViewModel>(context, listen: false);

  await authViewModel.login(
    _formData.email,
    _formData.password,
  );
}

Despite having a MaterialApp wrapped within the AppWidget, I still encounter an error related to a missing MaterialApp ancestor when attempting to display a dialog from my AuthViewModel.

Could someone help me understand why this error is occurring and how I can properly display the dialog while using the MultiProvider and ModularApp setup? I've checked my code, and I believe I have the necessary MaterialApp wrapping my AppWidget, but the error persists.

the error that i got is this:

E/RecaptchaCallWrapper( 4976): Initial task failed for action RecaptchaAction(action=signUpPassword)with exception - The email address is badly formatted.
D/InsetsController( 4976): show(ime(), fromIme=true)
E/flutter ( 4976): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: No MaterialLocalizations found.
E/flutter ( 4976): _InheritedProviderScope<AuthViewModel?> widgets require MaterialLocalizations to be provided by a Localizations widget ancestor.
E/flutter ( 4976): The material library uses Localizations to generate messages, labels, and abbreviations.
E/flutter ( 4976): To introduce a MaterialLocalizations, either use a MaterialApp at the root of your application to include them automatically, or add a Localization widget with a MaterialLocalizations delegate.
E/flutter ( 4976): The specific widget that could not find a MaterialLocalizations ancestor was:
E/flutter ( 4976):   _InheritedProviderScope<AuthViewModel?>
E/flutter ( 4976): The ancestors of this widget were:
E/flutter ( 4976):   ChangeNotifierProvider<AuthViewModel>
E/flutter ( 4976):   _NestedHook
E/flutter ( 4976):   _InheritedProviderScope<AuthUseCase?>
E/flutter ( 4976):   ChangeNotifierProvider<AuthUseCase>
E/flutter ( 4976):   _NestedHook
E/flutter ( 4976):   _InheritedProviderScope<ChatNotificationService?>
E/flutter ( 4976):   ChangeNotifierProvider<ChatNotificationService>
E/flutter ( 4976):   _NestedHook
E/flutter ( 4976):   MultiProvider
E/flutter ( 4976):   AppWidget
E/flutter ( 4976):   _ModularInherited
E/flutter ( 4976):   ModularApp
E/flutter ( 4976):   MediaQuery
E/flutter ( 4976):   _MediaQueryFromView
E/flutter ( 4976):   _ViewScope
E/flutter ( 4976):   View-[GlobalObjectKey FlutterView#70e35]
E/flutter ( 4976):   [root]
E/flutter ( 4976): #0      debugCheckHasMaterialLocalizations.<anonymous closure> (package:flutter/src/material/debug.dart:93:7)
E/flutter ( 4976): #1      debugCheckHasMaterialLocalizations (package:flutter/src/material/debug.dart:113:4)
E/flutter ( 4976): #2      showDialog (package:flutter/src/material/dialog.dart:1287:10)
E/flutter ( 4976): #3      AuthViewModel._showErrorDialog (package:estudo/src/feature/auth/viewmodel/auth_view_model.dart:82:5)
1

There are 1 answers

1
Buddy On

according to errors, dialog displayed by your AuthViewModel requires MaterialLocalizations but the provider context you are using to show the dialog does not have the necessary ancestor widgets that provide these localizations.

Use this code to make it correct -

class AuthViewModel extends ChangeNotifier {
  final AuthUseCase _authUseCase;
  final BuildContext appContext; // Add this line

  AuthViewModel(this._authUseCase, this.appContext);



  void _showErrorDialog(String msg) {
    showDialog(
      context: appContext, // Use appContext instead of context
      builder: (ctx) => AlertDialog(
        title: Text('error_occurred'.i18n()),
        content: Text(msg),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(ctx).pop(),
            child: Text('close'.i18n()),
          ),
        ],
      ),
    );
  }
}

In your AppWidget's build method, when you're creating the AuthViewModel, pass the BuildContext to it

ChangeNotifierProvider(
  create: (context) => AuthViewModel(
    AuthUseCase(),
    context, // Pass the context here
  ),
),

i hope your error will be solved, if you face any problem please let me know