3

I am still coming up to speed with dart and wanted to know if there was an easier way to not execute a statement if the value is null. See example below:

I can always do the if statements below for setting field3 and field4, but felt like something like field5 should work. But when I try to do that, it complains that a null check operator is used on a null value.

Also I don't want to change the Map to have a dynamic value.

Is there a single one liner to do what I am trying to do, or do I just need to check for null before setting the value.

  Map<String, Object> myMap = {};

  print('running now');
  try {
    myMap['field1'] = DummyClass.getString('hello');
    myMap['field2'] = DummyClass.getString('good');

    //Is there a more concise way to do this than the 2 options below?

    if (DummyClass.getOptionalString('goodbye') != null) {
      myMap['field3'] = DummyClass.getOptionalString('goodbye')!;
    }

    String? temp = DummyClass.getOptionalString('go');
    if (temp != null) {
      myMap['field4'] = temp;
    }

    // This gives an error 'null check operator used on a null value'
    // myMap['field5'] ??= DummyClass.getOptionalString('to')!;

  } catch (e) {
    print('error condition, $e');
  }

  print(myMap);
}

class DummyClass {

  static String getString(String? strParam) {
    String? retString = getOptionalString(strParam);
    if (retString == null) {
      throw ('nulls are not allowed');
    }
    return retString;
  }

  static String? getOptionalString(String? strParam) {
    if (strParam == null || strParam.length < 3) {
      return null;
    }
    return strParam;
  }
}

3 Answers 3

2

There's no built-in way to do what you want, but you could write a function (or extension method) to do it. For example:

extension MapTrySet<K, V> on Map<K, V> {
  void trySet(K key, V? value) {
    if (value != null) {
      this[key] = value;
    }
  }
}

and then you could do:

myMap.trySet('field3', DummyClass.getOptionalString('goodbye'));
myMap.trySet('field4', DummyClass.getOptionalString('go'));

Alternatively, if you really want to use normal Map syntax, you could create your own Map class that has a void operator []=(K key, V? value) override and does nothing when the value is null, but that probably would not be worth the effort.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this. This is probably the cleanest way to handle it at this point. I also have my map in another class and can just put the function in that class to handle the null case.
1

The issue is that the ??= operator assigns to the left if it is null. Expanded, it would look something like this:

a ??= b;

// Equivalent to:

if (a == null) {
  a = b;
}

Which is not something that you're trying to achieve. AFAIK, there is no such operator yet in Dart. However, you can try this:

final possiblyNullValue = '';
final myMap = <String, String>{};

myMap['key'] = possiblyNullValue ?? myMap['key'];

// Equivalent to:

if (possiblyNullValue != null) {
  myMap['key'] = possiblyNullValue;
}

// or:

myMap['key'] = possiblyNullValue != null? possiblyNullValue : myMap['key'];

Which would work in your case as a one-liner.

1 Comment

Not sure that works all that well as the value in myMap['key'] is also going to be null. I end up getting a bunch of errors that String? is nullable and String is not.
0

You could create your map with all entries, even null, and then filter the null values out:

void main() {
  try {
    final myMap = <String, dynamic>{
      'field1': DummyClass.getString('hello'),
      'field2': DummyClass.getString('good'),
      'field3': DummyClass.getOptionalString('goodbye'),
      'field4': DummyClass.getOptionalString('go'),
    }..removeWhere((k, v) => v == null);
    print(myMap);
  } catch (e) {
    print('error condition, $e');
  }
}

1 Comment

Interesting concept, but not sure it is worth the effort over just doing the if statement separately. Seems like there isn't a quick way to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.