-1

Can someone point out why I'm getting a null error where loading text within my localizations structure.

Error commented below at authSighInText.

The only thing I can think of is that _localizedValues is not initialized yet upon app launch. Should I be moving this earlier into main or something?

My language structure:

class AppLocalizationsDelegate extends LocalizationsDelegate<TextContent> {
  const AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => TextContent.languages().contains(locale.languageCode);

  @override
  Future<TextContent> load(Locale locale) {
    return SynchronousFuture<TextContent>(TextContent(locale));
  }

  @override
  bool shouldReload(AppLocalizationsDelegate old) => false;
}

class TextContent {
  TextContent(this.locale);
  final Locale locale;

  static TextContent of(BuildContext context) {
    return Localizations.of<TextContent>(context, TextContent)!;
  }

  // Add language list conglomeration from TextUtility here
  static final _localizedValues = <String, Map<String, String>>{
    'en': TextUtility.englishTexts(),
  };

  static List<String> languages() => _localizedValues.keys.toList();

  /* **********************************************************************************************
  Infrastructure Authentication Texts
  ************************************************************************************************/

  String get authSignInText {
    return _localizedValues[locale.languageCode]!['signIn']!;    // NULL ERROR HERE...???
  }

  String get authFormEmailText {
    return _localizedValues[locale.languageCode]!['email']!;
  }

  String get authFormPasswordText {
    return _localizedValues[locale.languageCode]!['password']!;
  }

...
}

Maps:

abstract class TextUtility {
  ///
  /// All english text maps to be manually hardcoded into this list.
  static List<Map<String, String>> englishTextLists = [
    InfrastructureAuthenticationText.authenticationText,
    InfrastructureFormValidationErrorText.invalidEmailText,
    InfrastructureDialogMessagesText.dialogMessagesText,
  ];

  ///
  /// English texts.
  ///
  /// Method conglomerates all texts from above english files into one map. This method is called
  /// within LanguageLocalizations TextContent.
  ///
  /// Returns:
  ///   [Map<String, String>]
  static Map<String, String> englishTexts() {
    Map<String, String> allEnglishTexts = {};
    for (int i = 0; i < englishTextLists.length; i++) {
      allEnglishTexts.addAll(englishTextLists[i]);
    }
    return allEnglishTexts;
  }
}

Language texts:

abstract class InfrastructureAuthenticationText {
  static const Map<String, String> authenticationText = {
    // Account actions
    'sign_in': 'Sign In',
    'sign_out': 'Sign Out',
    'sign_up': 'Sign Up',
    'sign_up punctuated': 'Sign Up.',

    ...
  };
}

Where text call is made:

Text(
            TextContent.of(context).authSignInText,
            style: ThemeEndpoints.primaryHeader(),
          ),
RobbB
  • 1,214
  • 11
  • 39

1 Answers1

1

You need to do that :

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) {
    runApp(EasyLocalization(
        supportedLocales: [Locale('en', 'US'), Locale('bn', 'BN')],
        path: 'lib/asset/translations',
        fallbackLocale: Locale('en', 'US'),
        saveLocale: true,
        child: MyApp()));
  });
}
  • I am not using the EasyLocalization library. But I’m assuming the same sort of approach would be what I’m looking for. The class must not be initialized by the time the first string is called. So I’ll have to initialize it manually in main. Thanks for the input, I’ll try to rig something up. – RobbB Sep 29 '22 at 10:51