6

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)!?

Husam Alhwadi
  • 383
  • 3
  • 11
  • It is impossible to do for now with Flutter's provided solution (intl package). But you can use another i18n package like https://pub.dev/packages/easy_localization or implementing your own library as shown in [Flutter docs](https://docs.flutter.dev/development/accessibility-and-localization/internationalization#an-alternative-class-for-the-apps-localized-resources). – vogdb Nov 13 '22 at 10:50

3 Answers3

5

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;
      ...
     }
pdurasie
  • 51
  • 1
  • 3
  • Thank you,I have no other choice, hopes to find more practical solution since i have a lot of dynamic text which need to be translated into 4 languages!! – Husam Alhwadi Apr 26 '22 at 17:35
  • 1
    @HusamAlhwadi did you come up with a less tedious solution? I am currently in the same predicament you were in. – RogyBear Oct 18 '22 at 18:49
  • @RogyBear it looks that the solution would be to use another i18n package like https://pub.dev/packages/easy_localization or implementing your own library as shown in [Flutter docs](https://docs.flutter.dev/development/accessibility-and-localization/internationalization#an-alternative-class-for-the-apps-localized-resources). – vogdb Nov 13 '22 at 10:48
  • but if you have list of 100 strings – appdev Jan 25 '23 at 05:43
1

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)

SoftWyer
  • 1,986
  • 28
  • 33
0

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.

pardus
  • 1
  • 1