Home > database >  Error: Expected a value of type '((List<dynamic>) => void)?', but got one of type
Error: Expected a value of type '((List<dynamic>) => void)?', but got one of type

Time:05-23

I'm trying to add an optional function to my widget:

final void Function(List<TList>)? onConfirm;

Getting this error:

"Error: Expected a value of type '((List) => void)?', but got one of type '(List) => void'

On the specified line of my widget:

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:multi_select_flutter/chip_display/multi_select_chip_display.dart';
import 'package:multi_select_flutter/util/multi_select_item.dart';
import 'package:new_day_flutter/generated/l10n.dart';
import 'package:new_day_flutter/presentation/common/widgets/form_fields/multiselect_dialog/fb_multiselect_dialog_field.dart';
import 'package:new_day_flutter/presentation/theme/palette.dart';

class BlMultiselectField<TList> extends StatefulWidget {
  const BlMultiselectField({
    Key? key,
    required this.name,
    required this.options,
    required this.labelText,
    this.onConfirm,
    this.hasFocus = false,
    this.initialValue = const [],
    this.dialogHeight,
    this.globalKey,
    this.onFocusChange,
  }) : super(key: key);

  final GlobalKey<FormFieldState>? globalKey;
  final List<MultiSelectItem<TList>> options;
  final List<TList> initialValue;
  final double? dialogHeight;
  final String name;
  final void Function(bool)? onFocusChange;
  final bool hasFocus;
  final String labelText;
  final void Function(List<TList>)? onConfirm;

  @override
  _BlMultiselectFieldState createState() => _BlMultiselectFieldState();
}

class _BlMultiselectFieldState<TList> extends State<BlMultiselectField<TList>> {
  @override
  Widget build(BuildContext context) {

    return FocusScope(
        child: FocusScope(
            child: Focus(
                onFocusChange: (isFocused) {
                  if (widget.onFocusChange != null) {
                    widget.onFocusChange!(isFocused);
                  }
                },
                child: FormBuilderField<List<TList>>(
                    name: widget.name,
                    initialValue: widget.initialValue,
                    builder: (FormFieldState<List<TList>> field) {
                      String labelText = (field.value ?? []).isNotEmpty
                          ? S.of(context).selectedCount(field.value!.length)
                          : widget.labelText;
                      return BlMultiSelectDialogField<TList>(
                        key: GlobalKey(),
                        chipDisplay: MultiSelectChipDisplay.none(),
                        searchable: true,
                        initialValue: widget.initialValue,
                        items: widget.options,
                        selectedValues: field.value ?? [],
                        title: Text(widget.labelText),
                        selectedColor: bluelabBlue,
                        dialogHeight: widget.dialogHeight,
                        decoration: const BoxDecoration(
                          border: Border(
                            bottom: BorderSide(color: bluelabBlue),
                          ),
                        ),
                        labelText: Text(
                          labelText,
                          style: const TextStyle(color: bluelabBlue),
                        ),
                        labelIcon: const Icon(
                          Icons.arrow_drop_down,
                          color: bluelabBlue,
                          size: 24,
                        ),
                        onConfirm: (value) {
                          widget.onConfirm?.call(value); //************* HERE *********
                          field.didChange(value);
                        },
                        onCancel: (context, value) {
                          setState(() {
                            
                          });
                          Navigator.pop(context);
                        },
                      );
                    }))));
  }
}

Using the widget like so:

BlMultiselectField<String>(
            globalKey: _filterDeviceGlobalKey,
            labelText: S.of(context).selectDevice,
            onConfirm: (x) {
              setState(() {});
            },
            name: 'devices',
            initialValue:
                widget.selectedDeviceIdentifiers.map((e) => e.key).toList(),
            options: devices
                .map((e) => MultiSelectItem<String>(e.key, e.value))
                .toList(),
            dialogHeight: 200,
          )

UPDATE It works when I change it to this:

final void Function(List<dynamic>)? onConfirm;

Don't know why it was not handling the generic though.

CodePudding user response:

I think you should do this instead:

final void Function(List<TList>?) onConfirm;

CodePudding user response:

This

_BlMultiselectFieldState createState() => _BlMultiselectFieldState();

should really be:

_BlMultiselectFieldState<TList> createState() => _BlMultiselectFieldState<TList>();

Otherwise the TList of your state class will always be dynamic and not match the TList type of your widget. Which is a problem when you use a function that has TList in it's signature.

  • Related