Home > Software engineering >  If block being skipped over for no reason
If block being skipped over for no reason

Time:10-06

I have a small function that returns a String from an asset or a build-time environment.

String getData([String? assetName]){
  String data = const bool.hasEnvironment('FIREBASE_CONFIG')
      ? const String.fromEnvironment(
          'CONFIG',
        )
      : "";
  assetName = assetName ?? 'assets/config.json';

  if (data.isEmpty) {
    rootBundle.loadString(assetName).then((value) => data = value);
  }

  return data;
}

The problem is that the if block is skipped over. I have ran the code in debug and data.isEmpty is true. I am not using final in the declaration. I don't now why this is happening? is there something I am missing?

CodePudding user response:

loadString method's complete end of all sync operation. If you like to get data and return from loadString you can convert the getData to a future.

Future<String> getData([String? assetName]) async {
  String data = const bool.hasEnvironment('FIREBASE_CONFIG')
      ? const String.fromEnvironment(
          'CONFIG',
        )
      : "";
  assetName = assetName ?? 'assets/config.json';

  if (data.isEmpty) {
    return await rootBundle.loadString(assetName);
  }

  return data;
}

To have more clear view run this snippet

Future<String> loadString() async {
  print("loadString started");
  await Future.delayed(Duration(seconds: 1));
  print("loadString wait ended");
  return "loadString";
}

String getData([String? assetName]) {
  String data = "";
  assetName = assetName ?? 'assets/config.json';

  if (data.isEmpty) {
    loadString().then((value) => data = value);
    print("data.isEmpty $data");
  }
  print("just before return $data");
  return data;
}

void main(List<String> args) {
  final result = getData();
  print("on main result $result");
}

It will show

loadString started
data.isEmpty
just before return
on main result
loadString wait ended

So you can convert

Future<String> getData([String? assetName]) async {
  String data = "";
  assetName = assetName ?? 'assets/config.json';

  if (data.isEmpty) {
    data = await loadString();
    print("data.isEmpty $data");
  }
  print("just before return $data");
  return Future.value(data);
}

void main(List<String> args) async {
  final result = await getData();
  print("on main result $result");
}

Will contain result as

loadString started
loadString wait ended
data.isEmpty loadString
just before return loadString
on main result loadString
  • Related