Best approach to null safe AppLocalization strings

Viewed 4064

Question

I am using AppLocalizations.of(context).myString to internationalize strings in my null safe flutter app.

My IDE tells me that AppLocalizations.of(context) can return null. What's the best approach to handle this? Is there a way to ensure AppLocalizations.of(context) never returns null?

Currently, I am resorting to the following approach:

AppLocalizations.of(context)?.myString ?? 'Fallback string'

Full Project Code

Pubspec.yaml

name: Sample Intl Project
description: A sample project
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: ">=2.12.0-133.2.beta <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0-nullsafety.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  generate: true

l10n.yaml

arb-dir: lib/l10n
template-arb-file: app_en_US.arb
output-localization-file: app_localizations.dart

l10n/app_en_US.arb

{
  "helloWorld": "Hello World!",
  "@helloWorld": {
    "description": "Greeting"
}

l10n/app_en.arb

{
  "helloWorld": "Hello World!"
}

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: Home()
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        AppLocalizations.of(context)?.helloWorld ?? 'Hello World!'
      ),
    );
  }
}
4 Answers

add this line in l10n.yaml:

nullable-getter: false

If you are sure, that AppLocalizations.of(context) will always return a valid AppLocalizations instance (which is true for your sample application), you can use:

AppLocalizations.of(context)!.myString

The ! operator tells Dart, that AppLocalizations.of(context) will never return null and acts like a cast from the nullable AppLocalizations? to the non-nullable AppLocalizations.

Note: If AppLocalizations.of(context) returns null at runtime, then AppLocalizations.of(context)! will throw an exception.

As also said in a comment, I would ask you to share more of your code, your pubpsec your l10n.yaml and anything else relevant as far as you can.

My suggestion until then is to update intl in your dependencies from the latest to:

intl: ^0.17.0-nullsafety.2

I assume that nullsafety will not be left to the end devs and it will be standard very soon without having to think about it.

As it seems, your app always expects string value from AppLocalizations texts.
I suggest ensuring string is null safe, and that should solve your problem.
Here is snippets that you can use.

  1. Define a string extension
// a string extension
extension MyStringExtentions on String {
  String nullSafeStr() =>
      (this == null || this.isEmpty || this == "null") ? "" : this;
}

// OR a static method
//static String nullSafeStr(String source) => (source == null || source.isEmpty || source == "null") ? "" : source;

now you can use either of them, see example using the new extension

// .nullSafeStr() becomes available wherever you import the extension method 
AppLocalizations.of(context).helloWorld.nullSafeStr()

// the alternative way is to call the static method  
.nullSafeStr(AppLocalizations.of(context).helloWorld);  
Related