Why do I get an error while coding the constructor? - flutter

I have the following code and it gives an error:
The parameter 'product' can't have a value of 'null' because of its type, but the implicit default value is 'null'.
here is my code:
final Product product;
const ItemCard({
Key? key,
this.product, // error here
}): super(key: key);

Add in the 'required' keyword before product.
Consider writing as follows:
final Product _product;
const ItemCard({Key? key, required Product product}) :
_product = product, super(key: key);
These are changes resulting from null safety link

here:
final Product product;
const ItemCard({
Key? key,
Product myProduct,
}):
product = myProduct,
super(key: key);

Related

How can I define a specialized type for super params?

I have this class A that extends a class B. Class B has a Key parameter on its constructor.
But I wanted class A to accept stricty LocalKey values instead of any Key value, using super params.
It had the following class constructor:
const A({
required this.child,
LocalKey? key,
}) : super(key: key);
And I refactored it to use super params:
const A({
required this.child,
super.key,
});
But then it lost the ability to make the Key parameter accept stricty LocalKey values.
The best solution I could think of was to add an assert so it fails on runtime, it could help but it only works on debug builds:
const A({
required this.child,
super.key,
}) : assert(key is LocalKey);
Is there a better way to write it so it accepts only LocalKey parameters?

parameter cant have the value of null because of its type, but implecit default value is null?

const LeftBar({Key key, #required this.barWidth}) : super(key: key);
enter image description here
here i am getting error at key and barWidth

How to make a widget require one of two properties?

So I have a widget that can accept a color or a gradient property :
class OuterWheel extends StatelessWidget {
final double outerRadius;
final double innerRadius;
final TextStyle textStyle;
final double percentage;
final int decimals;
final Color? color;
final List<Color>? gradient;
const OuterWheel({
Key? key,
required this.outerRadius,
required this.innerRadius,
required this.textStyle,
required this.percentage,
required this.decimals,
this.color,
this.gradient,
}) : super(key: key);
I would like to make it like in TypeScript where you could have a union type like Color|List<Color> , so I could only use one property, but apparently we don't have that in Dart.
So how can I make so that you have to choose one of these two fields?
What about mutual exclusive operator?
const OuterWheel({
Key? key,
required this.outerRadius,
required this.innerRadius,
required this.textStyle,
required this.percentage,
required this.decimals,
this.color,
this.gradient,
}) : assert((color == null) ^ (gradient == null), 'color and gradient are mutually exclusive'), super(key: key);
This way you ensure that only one of them, but not both, is not null.

Why is key required in constructor?

I have created class which extend StatefulWidget
class RegistrationPage extends StatefulWidget {
final String email;
const RegistrationPage({Key key, required this.email}) : super(key: key);
#override
_RegistrationPage createState() => _RegistrationPage();
}
The problem is android studio force me to put required before Key key. I googled some of examples how to pass values from screen to another screen and I have never seen that someone used required with Key.
I do it within:
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => RegistrationPage(email: email),
),
);
so just to pass email value. I need to make Key nullable to make it work.
Am I doing something wrong?
Because you're using null-safe Dart and key can't be null because it has a non-nullable type Key.
Solutions:
Use required
FooPage({required Key key});
Make key nullable.
FooPage({Key? key});
Remove key altogether.
FooPage();
I think your project is in null safety, with null safety a variable or object cannot be null execept if it is declared nullable.
Try adding a ? after Key:
class RegistrationPage extends StatefulWidget {
final String email;
const RegistrationPage({Key? key, required this.email}) : super(key: key);
#override
_RegistrationPage createState() => _RegistrationPage();
}
or you can simply delete the Key override:
class RegistrationPage extends StatefulWidget {
final String email;
const RegistrationPage({required this.email});
#override
_RegistrationPage createState() => _RegistrationPage();
}
I suggest you to read https://dart.dev/null-safety/understanding-null-safety
You're not doing anything wrong by making Key key nullable. The super constructors that you're passing the key to accept the nullable type.
So
const RegistrationPage({Key? key, required this.email}) : super(key: key);
is the norm as there is no reason to constrain the type by making it non-nullable and required.
If you have no need for keys with this widget, you can omit the super constructor and the key parameter completely.

Make Function parameter optional in custom widget flutter

I try to create some custom widgets with some parameters in the constructor. This widget has some optional and required parameters.
how can make Function type parameter optional in my Widget.
class TextInputWithIcon extends StatefulWidget {
final String iconPath;
final String placeHolder;
final Function(bool) onFocusChange;
const TextInputWithIcon(
{Key key,
#required this.iconPath,
this.placeHolder = "",
this.onFocusChange})
: super(key: key);
#override
_TextInputWithIconState createState() => _TextInputWithIconState();
}
class _TextInputWithIconState extends State<TextInputWithIcon> {
#override
Widget build(BuildContext context) {
return MY_WIDGET;
}
}
Optional parameters can be either positional or named, but not both.
Named parameters are optional by default so you don't have to assign the default value.
If a parameter is optional but can’t be null, provide a default value.
With null safety
class TextInputWithIcon extends StatefulWidget {
final String iconPath;
final String placeHolder;
final Function(bool)? onFocusChange; // nullable and optional
const TextInputWithIcon(
{Key? key,
required this.iconPath, // non-nullable and required
this.placeHolder = "", // non-nullable but optional with a default value
this.onFocusChange, // nullable and optional
})
: super(key: key);
#override
_TextInputWithIconState createState() => _TextInputWithIconState();
}
Without null safety
const TextInputWithIcon(
{Key key,
#required this.iconPath,
this.placeHolder = "",
this.onFocusChange
})
: super(key: key);
Usage:
void _focusChanged(bool value) {
// using null-aware operator (for both with and without null safety)
onFocusChange?.call(value);
// or without null-aware operator
// with null safety
if(onFocusChange != null) {
onFocusChange!(value);
}
// without null safety
if(onFocusChange != null) {
onFocusChange(value);
}
}
Dart 2.17 update:
Although it often makes sense to place positional arguments first, named arguments can be placed anywhere in the argument list when it suits your API:
repeat(times: 2, () {
...
});
Have a look at Optional Parameters to understand better.
Edit: Thank you Jonah Williams to clarification.
You can use a default value that does nothing:
class TextInputWithIcon extends StatefulWidget {
final String iconPath;
final String placeHolder;
final Function(bool) onFocusChange;
const TextInputWithIcon(
{Key key,
#required this.iconPath,
this.placeHolder = "",
this.onFocusChange = _dummyOnFocusChange})
: assert(onFocusChange != null), super(key: key);
#override
_TextInputWithIconState createState() => _TextInputWithIconState();
static dynamic _dummyOnFocusChange(bool val) {}
}
I created a static named function instead of just a closure as a default value because closures are not const and currently default values need to be const.
I added the assert(...) to ensure that an error is shown when null is passed explicitly.
Another option if you don't like named parameters (like me :/) is:
function_name (argument1, [argument2]) {
// statements
}
arguments in brackets are optional.
source