Search code examples
localizationflutter-getx

Using JSON Files for localization in GetX


I am trying to read translation files eg. en.json to use with GetX localization. I tried the following code but no success. Is there any better way of doing it? Somebody suggested using auto_localize with GetX, but I'll really appreciate if I can proceed without an extra package

  Map<String, Map<String, String>> get keys => {
        "ar": readJson("ar"),
        "en": readJson("en"),
}

I tried loading the localization information using the following function

 // Fetch content from the json file
  Map<String, String> readJson(String languageCode) {
    Map data = {};
    rootBundle
        .loadString('assets/translations/$languageCode.json')
        .then((response) {
      data = json.decode(response);
    });
    return data.map((key, value) {
      return MapEntry(key, value.toString());
    });
  }

DebugPrint() gets shows that the files were successfully loaded. However, trying to display the loaded Maps doesn't work


Solution

  • The readJson should be Future and because of that the empty Map returned at the end.

    The way i did

    • create languages.json file and put all texts to it.
    [
      {
        "name": "English",
        "code": "en_US",
        "texts": {
          "hello": "Hello World"
        }
      },
      {
        "name": "Arabic",
        "code": "ar_AE",
        "texts": {
          "hello": "مرحبا بالعالم"
        }
      }
    ]
    
    • implement localization class like this
    class LocalizationService extends Translations {
    
      @override
      Map<String, Map<String, String>> get keys => {};
    
      static Future<void> initLanguages() async {
        final _keys = await readJson();
        Get.clearTranslations();
        Get.addTranslations(_keys);
      }
    
      static Future<Map<String, Map<String, String>>> readJson() async {
        final res = await rootBundle.loadString('assets/languages.json');
        List<dynamic> data = jsonDecode(res);
        final listData = data.map((j) => I18nModel.fromJson(j)).toList();
        final keys = Map<String, Map<String, String>>();
        listData.forEach((value) {
          final String translationKey = value.code!;
          keys.addAll({translationKey: value.texts!});
        });
        return keys;
      }
    }
    

    As you see after getting the Map data, i used Get.addTranslations(); to set language keys. this is a GetX function to add languages on air!

    • create model class to parse json data
    class I18nModel {
      String? name;
      String? code;
      Map<String, String>? texts;
    
      I18nModel(
          {this.name, this.code, this.texts});
    
      I18nModel.fromJson(Map<String, dynamic> json) {
        name = json['name'];
        code = json['code'];
        if (json['texts'] != null) {
          texts = Map<String, String>.from(json['texts']);
        }
      }
    }
    
    • And finally call await LocalizationService.initLanguages(); before going to your first Route.