0

I am somewhat new to dart and am having trouble with default values for parameters. I am creating a class and in some cases the parameters can be null. In those cases I want to apply the default value. So in the example below the fieldType parameter to TargetField can be null and if that is the case I want to use the default.

The error I am getting is: Unhandled exception: type 'Null' is not a subtype of type 'FieldType'

I can check on the caller side if the value is null and then pass a default value (Comment 1), but I want to set the default value in the TargetField class (Comment 2). I would also prefer to keep the fieldType field not nullable, because it shouldn't ever be null.

Thanks for your help.

enum FieldType {
  string,
  int,
  date,
  array,
  lookup,
  map
}

main() {
  Map<String, Map> myMap = {
    'target0': { 'type': FieldType.string},
    'target1': { 'static': 'hello'},
    'target2': { 'static': 'goodbye'},
    'target3': { 'type': FieldType.date},
    };

  print('running now');
  myMap.forEach((k, v) {
    print('running now, $k : $v');
    TargetField tf = TargetField(fieldName: k, fieldType: v['type']);

    // Comment 1: Would like to avoid doing this, would be more comfortable doing
    // something on the TargetField side to set the default value, not the caller.

    // TargetField tf = TargetField(fieldName: k,
    //     fieldType: (v['type'] != null) ? v['type'] : FieldType.string);
    tf.printType();
  }
  );
}

class TargetField {

  FieldType fieldType;
  final String fieldName;

  TargetField({required this.fieldName, this.fieldType = FieldType.string}) {
    //Comment 2: Can I do something here to set the value to the default value if the
    //parameter passed is null?
  }

  printType() {
    print('$fieldName type = ${fieldType.name}');
  }

}

1 Answers1

1

You can make a constructor use the same default if an argument is omitted or null by making the default argument null and adding logic to fall back to the desired default value for the member. Note that the construction parameter will be nullable, but the member does not need to be. For example:

class TargetField {
  FieldType fieldType;
  final String fieldName;

  TargetField({required this.fieldName, FieldType? fieldType})
    : fieldType = fieldType ?? FieldType.string;

This technique is also useful for using non-const values as default arguments.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • Perfect, thank you. I knew there was a way to do it, but just couldn't put it together. Not that it matters much, but where you have String? it should be FieldType?. Thanks again. – Brian Elkin Feb 16 '22 at 20:20
  • Oops, I got them mixed up because the parameter order didn't match the member order. Fixed. – jamesdlin Feb 16 '22 at 20:23
  • This only applies to constructors, doesn't it? Is there something similar for methods other than constructors? – Stacky Jul 19 '22 at 09:34
  • @Stacky A non-constructor could do `fieldType = fieldType ?? FieldType.string;` as a statement rather than being part of an initializer list. The same principle applies. – jamesdlin Jul 19 '22 at 17:39