I do use intl_utils as i thought that were the ‘official’ way of doing this.
But as i never had problems with my approach, so it may help some of you too.
In short, this solution don’t has to pass a BuildContext around.
First of all, my localization is retrieved through the context via S.of(context); (S are my AppLocalizations)
And hence i have a class, i created an interface
import "../../../generated/l10n.dart";
//ignore: one_member_abstracts .
abstract class Localizable<T> {
T localize(S s);
}
So, i’ve created a LocalizableException
abstract class LocalizableException implements Localizable<String>, Exception {
/// {@template shared.logic.localizable_exception}
/// will be shown instead of [getMessage].
/// For example: A network call returns a more specific exception message than the default localized message
/// {@endtemplate}
final String? message;
const LocalizableException({this.message});
/// a default localized message
@mustBeOverridden
String getMessage(S s) => throw UnimplementedError();
/// show the message provided by the exception thrower, if any. Otherwise a fallback is provided by [getMessage].
@override
String localize(S s, {bool ignoreOverride = false}) {
if (message != null && ignoreOverride) return message!;
return getMessage(s);
}
}
With that, exceptions thrown in my business logic are piped through a message queue and can than be listened by inherited widgets or other ‘consumers’.
This way, my UI is retrieving my exceptions and can correctly localize them.
void _startUserErrorListener() {
subscribe(
queueId: Queue.userError.name,
callback: (Message message) {
SnackBar snackbar;
switch (message) {
case LocalizableMessage(payload: LocalizableException payload):
snackbar = ErrorSnackbar.exception(
context: scaffoldMessengerKey.currentContext!,
exception: payload,
);
default:
snackbar = ErrorSnackbar(
context: scaffoldMessengerKey.currentContext!,
message: message.payload.toString(),
);
}
_showSnackbar(snackbar);
},
);
}
I’ve seen other packages that don’t elevate the BuildContext and only use static localizations which i think is also fine in most apps, as i personally never had the case to localize a subtree differently.