slang icon indicating copy to clipboard operation
slang copied to clipboard

Unsure how to use slang with riverpod + locale preference

Open richardjharris opened this issue 2 years ago • 3 comments

For my app the Locale comes out of a riverpod provider (ref.watch(settingsControllerProvider.select((s) => s.appLocale())) and I don't know how to connect this to the slang interface.

For the intl module, you just make your top-level widget a ConsumerWidget, it uses ref.watch as above, then passes that locale to the MaterialApp locale argument. Then whenever the locale is changed, the entire widget tree is rebuilt with the new language.

With slang, when if I update the locale, the widget tree is not rebuilt, and stays in English.

I am not sure what I am doing wrong here. My widget tree is main() -> runApp(TranslationProvider(child: MyApp())) where MyApp calls appLocale = ref.watch(...) and returns MaterialApp(locale: appLocale). Debug print shows the MaterialApp is being created with a new locale, but nothing is updated.

If I manually call LocaleSettings.setLocale( in the build method of MyApp, I get the error FlutterError (setState() or markNeedsBuild() called during build. This TranslationProvider widget cannot be marked as needing to build because the framework is already in the process of building widgets. ... .

richardjharris avatar Aug 28 '22 16:08 richardjharris

I got it working by following https://github.com/Tienisto/slang/blob/master/slang/documentation/dependency_injection.md

It works fine.

I prefer i18n because i18n allows you to refresh the top-level widget, then get translations via AppLocalizations.of(context) from anywhere. The slang solution requires riverpod to be used everywhere, which is not always convenient.

I don't understand the myEnResolver part, so I skipped that.

richardjharris avatar Aug 28 '22 16:08 richardjharris

Hi,

yep, riverpod is the injection solution in your case. Your current solution is quite clean because now the translations are also depending on some riverpod provider.

There are also some other solutions which are more "dirty" but more convenient:

// in your top-level build method
ref.listen<int>(localeProvider, (prev, curr) {
      LocaleSettings.setLocaleRaw(curr);
});

// A: call the static instance directly without provider (do not wrap your app with TranslationProvider)
String a = t.myString;

// B: or access the provider (TranslationProvider is needed here)
final t = Translations.of(context);
String a = t.myString;

Tienisto avatar Aug 28 '22 18:08 Tienisto

myEnResolver is the English plural resolver. The default plural handling will be used if you leave it out :)

Tienisto avatar Aug 28 '22 18:08 Tienisto

Closed due to inactivity

Tienisto avatar Feb 13 '23 00:02 Tienisto