Ekrem Kangal
Ekrem Kangal

Reputation: 125

using the default value if the parameter is null

How can I write the code block marked in the picture below more properly. My goal is to send the default value to the parameter if the availableColors variable is null.

Code Block

showDialog<Color>(
  context: context,
  builder: (BuildContext context) {
    return OrientationBuilder(
      builder: (context, orientation) {
        return ResponsiveDialog(
          context: context,
          title: title,
          headerColor: headerColor,
          headerTextColor: headerTextColor,
          backgroundColor: backgroundColor,
          buttonTextColor: buttonTextColor,
          child: availableColors == null ? BlockPicker(
            pickerColor: selectedColor,
            onColorChanged: (color) => selectedColor = color,
          ): BlockPicker(
            pickerColor: selectedColor,
            availableColors: availableColors,
            onColorChanged: (color) => selectedColor = color,
          ),  
          okPressed: () => Navigator.of(context).pop(selectedColor),
        );
      },
    );
  },
).then((selection) {
  if (onChanged != null && selection != null) onChanged(selection);
});

I can't change BlockPicker. It comes from an external library.

class BlockPicker extends StatefulWidget {
  const BlockPicker({
    @required this.pickerColor,
    @required this.onColorChanged,
    this.availableColors = _defaultColors,
    this.layoutBuilder = defaultLayoutBuilder,
    this.itemBuilder = defaultItemBuilder,
  });

Upvotes: 6

Views: 16106

Answers (3)

jamesdlin
jamesdlin

Reputation: 89946

Unfortunately, when invoking a function, Dart does not provide a good way to conditionally use its default argument. (There is at least one language proposal to provide such a mechanism.)

In general, you'd usually have to duplicate the function's default argument (and hope it doesn't change).

In this case, BlockPicker doesn't allow you to do that directly since its default value for availableColors is private. However, its availableColors property is public, so you could construct a dummy BlockPicker and extract the default value it used. For example:

final defaultAvailableColors =
    BlockPicker(
      pickerColor: Colors.black,
      onColorChanged: (_) {},
    ).availableColors;

...
          child: BlockPicker(
            ...
            availableColors: availableColors ?? defaultAvailableColors,
            ...
          ),  
...

In the long-term, I would file an issue against BlockPicker and request that either the defaults be made public or that they're used when the arguments are null.

Upvotes: 7

Gonzalo Gauto
Gonzalo Gauto

Reputation: 181

I dont know if availableColors is a list of Colors but instead of using this code:

child: availableColors == null ? BlockPicker(
            pickerColor: selectedColor,
            onColorChanged: (color) => selectedColor = color,
          ): BlockPicker(
            pickerColor: selectedColor,
            availableColors: availableColors,
            onColorChanged: (color) => selectedColor = color,
          ), 

u can use this one:

if avaliableColors is not null use availableColors if not use defaultColors

child: BlockPicker(
            pickerColor: selectedColor,
            availableColors: availableColors??defaultColors,
            onColorChanged: (color) => selectedColor = color,
          ),  

defaultColor must be a value like availableColors.

Upvotes: 1

encubos
encubos

Reputation: 3283

I really don't know if I understand your question correctly.

Probably you need to change the class BlockPicker. Give a default value to some properties, so you dont need to pass them.

Example:

class MyText extends StatelessWidget {
  final String texto;

  MyText({this.texto = "default value"});

  @override
  Widget build(BuildContext context) {
    return Text(texto);
  }
}

And this class, can be used like:

// with a parameter, print "my data"
MyText(texto: "my data"),

// no parameter, takes the default, print "default value"
MyText(),

If you cant change BlockPicker maybe you can do something like:

child: BlockPicker(
            pickerColor: selectedColor,
            availableColors: (availableColors == null) 
               ? "your-defaults-color" 
               : availableColors,
            onColorChanged: (color) => selectedColor = color,
          )

One last way. You can extract that part and call the function:

  Widget buildMyText(col) {
      if (col == null) {
          return BlockPicker(
            pickerColor: selectedColor,
            onColorChanged: (color) => selectedColor = color,
          ); 
      } else {
          return BlockPicker(
            pickerColor: selectedColor,
            availableColors: availableColors,
            onColorChanged: (color) => selectedColor = color,
          ); 
      }    
  }

 // use
 child: buildMyText(availableColors)

Upvotes: 0

Related Questions