In freezed, how can I directly reference uncommon parameter tin the union type?

34 Views Asked by At

According to freezed document. I created an union type class FormItem, which like this

@freezed
abstract class FormItem with _$FormItem {
  const factory FormItem.ShortText({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required bool isHighlighted,
    required Validator validators,
  }) = ShortTextItem;

  const factory FormItem.LongText({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required Validator validators,
  }) = LongTextItem;

  const factory FormItem.Number({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required Validator validators,

  }) = NumberItem;

  const factory FormItem.SectionHeading({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
  }) = SectionHeadingItem;


  const factory FormItem.ImageUpload({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required Validator validators,

  }) = ImageUploadItem;

  const factory FormItem.FileUpload({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required Validator validators,

  }) = FileAttachmentItem;

  const factory FormItem.SingleSelect({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required bool isHighlighted,
    required List<SelectionOption> options,
    required Validator validators,

  }) = SingleSelectItem;

  const factory FormItem.MultiSelect({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required List<SelectionOption> options,
    required Validator validators,

  }) = MultiSelectItem;

  const factory FormItem.CheckBox({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required Validator validators,

  }) = CheckBoxItem;

  const factory FormItem.DateItem({
    required String id,
    required int index,
    required FormItemType type,
    required String title,
    required String description,
    required Validator validators,

  }) = DateItem;

  const FormItem._();

  factory FormItem.fromJson(Map<String, dynamic> json) => _$FormItemFromJson(json);
}

and the typeSingleSelectItem has an uncommon parameter which named options:

abstract class SingleSelectItem extends FormItem {
  const factory SingleSelectItem(
      {required final String id,
      required final int index,
      required final FormItemType type,
      required final String title,
      required final String description,
      required final bool isHighlighted,
      required final List<SelectionOption> options,
      required final Validator validators}) = _$SingleSelectItemImpl;
  const SingleSelectItem._() : super._();

  factory SingleSelectItem.fromJson(Map<String, dynamic> json) =
      _$SingleSelectItemImpl.fromJson;

  @override
  String get id;
  @override
  int get index;
  @override
  FormItemType get type;
  @override
  String get title;
  @override
  String get description;
  bool get isHighlighted;
  List<SelectionOption> get options;
  Validator get validators;
  @override
  @JsonKey(ignore: true)
  _$$SingleSelectItemImplCopyWith<_$SingleSelectItemImpl> get copyWith =>
      throw _privateConstructorUsedError;
}

in my widget code, I use function getFormItemType to identify the type

getFormItemType(FormItem formItem) {
    var res;
    switch (formItem) {
      case ShortTextItem(:String id, :int index, :FormItemType type, :String title, :String description, :bool isHighlighted, :Validator validators):
        res = ShortTextItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          isHighlighted: isHighlighted,
          validators: validators,
        );
        break;

      case LongTextItem(:String id, :int index, :FormItemType type, :String title, :String description, :Validator validators):
        res = LongTextItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          validators: validators,
        );
        break;

      case NumberItem(:String id, :int index, :FormItemType type, :String title, :String description, :Validator validators):
        res = NumberItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          validators: validators,
        );
        break;

      case SectionHeadingItem(:String id, :int index, :FormItemType type, :String title, :String description):
        res = SectionHeadingItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
        );
        break;

      case ImageUploadItem(:String id, :int index, :FormItemType type, :String title, :String description, :Validator validators):
        res = ImageUploadItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          validators: validators,
        );
        break;

      case FileAttachmentItem(:String id, :int index, :FormItemType type, :String title, :String description, :Validator validators):
        res = FileAttachmentItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          validators: validators,
        );
        break;

      case SingleSelectItem(:String id, :int index, :FormItemType type, :String title, :String description, :bool isHighlighted, :List<SelectionOption> options, :Validator validators):
        res = SingleSelectItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          isHighlighted: isHighlighted,
          options: options,
          validators: validators,
        );
        singleSelectItem = res;
        var singleSelectOptions = formItem.options;
        break;

      case MultiSelectItem(:String id, :int index, :FormItemType type, :String title, :String description, :List<SelectionOption> options, :Validator validators):
        res = MultiSelectItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          options: options,
          validators: validators,
        );
        break;

      case CheckBoxItem(:String id, :int index, :FormItemType type, :String title, :String description, :Validator validators):
        res = CheckBoxItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          validators: validators,
        );
        break;

      case DateItem(:String id, :int index, :FormItemType type, :String title, :String description, :Validator validators):
        res = DateItem(
          id: id,
          index: index,
          type: type,
          title: title,
          description: description,
          validators: validators,
        );
        break;
    }
    return res;
  }

in SingleSelectItem section, I can directly use the options parameter like :

var singleSelectOptions = formItem.options;

However, outside of this function, it will say "The getter 'options' isn't defined for the type 'FormItem'", even though I use is to identify the type as SingleSelectItem.

  void _initializeData() {
    formItem = getFormItemType(widget.formItem);

    if(formItem is SingleSelectItem){
     debugPrint("the list is : ${formItem?.options}");
    }
    setState(() {

    });

  }

what if I wanna outside getFormItemType to use the parameter options? is there any better way than the below code?

  formItem = getFormItemType(widget.formItem);
  SingleSelectItem item = formItem as SingleSelectItem;
0

There are 0 best solutions below