passing dynamic strings to AppLocalizations.of(context)! in Flutter

6.9k views Asked by At

right now Im working in App using Flutter and I have 4 different languages, I use json (arb files) for localization (translation)

I need to pass different string values which app fetch them using API's as shown in example below

AppLocalizations.of(context)!snapshot.data![index].state_pickup[0]

however "AppLocalizations.of(context)!" doesn't fetch the return data from snapshot.data![index].state_pickup[0] and instead it looks for it as string and tries to search for match string name in AppLocalization.dart class?

Any idea how I can pass dynamic string arguments to AppLocalizations.of(context)!?

4

There are 4 answers

4
pdurasie On

What you are trying to do, invoking a method by its name at runtime, is called reflection, and this is not supported by Flutter natively (though there are packages that try to emulate this, but I have no experience with them).

What will work for you, even though it might be tedious, is manually mapping your value from the API to the corresponding method from AppLocalizations.of(context).

String localizedString = getLocalizedString(snapshot.data![index].state_pickup[0], context);

String getLocalizedString(String key, BuildContext context) {
  switch (key) {
    case "possible_api_value_1":
      return AppLocalizations.of(context)!.possibleApiValue1;
    case "possible_api_value_2":
       return AppLocalizations.of(context)!.possibleApiValue2;
      ...
     }
0
SoftWyer On

An alternative is to use (abuse?) the ICU Select option.

This is the equivalent of a switch case statement in the translation file itself, rather than coding it as described by @pdurasie.

As described in the Localizely documentation (here and here)

Select statements take the form that matches passed variable or defaults to other form, which is required.

{
  "selectExample": "Today is {gender, select, male {his} female {her} other {their} } birthday"
  "@selectExample": {
    "placeholders": {
      "gender": {}
    }
  }
}

If we pass gender variable with the value male to the example, it will print "Today is his birthday".

The Flutter code for the poster would look like:

AppLocalizations.of(context).selectExample(snapshot.data![index].state_pickup[0])

It's unclear if there are any limits on the number of select options. (ICU ref docs)

0
pardus On

Using the Flutter easy_localization package, you can use curly braces '{}' in your JSON translation files to handle dynamic string expressions. Below is the format for the Flutter code and the JSON file:

en_US.json:
{"before_notification": "Notifications will be set to {} minutes ago."}

 Flutter:
Text(tr('before_notification', args:[_selectedMinutes.round()]),), 

In this setup, you define your translation key in the JSON file with curly braces '{}' as a placeholder for dynamic values. Then, in your Flutter code, you use the tr() function to access the translation, and you pass the dynamic value to the placeholder using the args parameter.

By following this structure, the easy_localization package will replace the placeholder {} in your translation with the corresponding dynamic value at runtime. This way, you can easily display translated strings with dynamic content based on the selected language.

0
Christian Onwe On

I faced similar situation requiring dynamic translation keys parsed to AppLocalizations and created l10n_mapper_annotation and l10n_mapper_generator packages to address this.

As flutter does not support reflection (but dart does) the solution tries to emulated this by generating localization part file using specified setup configuration options (which you can find in the pub documentation). This supports parsing dynamic translation keys and defines other helpful extension methods.

Example setup

  • Install l10n_mapper_annotation and l10n_mapper_generator packages (in pubspec.yaml)

  • Install l10n_mapper_generator as global dependency dart pub global activate l10n_mapper_generator (required to run in terminal)

  • Setup configuration options (find example in pub documentation)

  • Run the below scrips in succession

    • generate localization-related files run: flutter gen-l10n

    • annotate app_localizations to generate app_localizations.g.dart file run: dart pub run l10n_mapper_generator --gen-mapper

Example usage As the generated part file consists of key-value pair returning translation keys values, below illustrates usage

final applicationName = context.l10nParser('application_name'); // Localization mapper
final depositTimeFrame = context.l10nParser('deposit_timeframe'); // Instant

// parsing placeholder parameters
final convertBeforeWithdraw = context.l10nParser('convert_before_withdraw', arguments: ['CAD', 'EUR']); // * For withdrawing your CAD you first need to convert it back to EUR