Reputation: 126924
I have the following Dart function and I am now using null safety:
void calculate({int factor}) {
// ...
}
The analyzer complains that:
The parameter 'factor' can't have a value of 'null' because of its type, and no non-null default value is provided.
This is also the case for my StatelessWidget
in Flutter:
class Foo extends StatelessWidget {
const Foo({Key key}): super(key: key);
// ...
}
I get the following error:
The parameter 'key' can't have a value of 'null' because of its type, and no non-null default value is provided.
How can I resolve this issue?
Upvotes: 143
Views: 199960
Reputation: 126563
This is the initial error message:
lib/main.dart:23:19: Error: The parameter 'key' can't have a value of 'null' because of its type 'Key', but the implicit default value is 'null'.
- 'Key' is from 'package:flutter/src/foundation/key.dart' ('/C:/Data/flutter/packages/flutter/lib/src/foundation/key.dart'). Try adding either an explicit non-'null' default value or the 'required' modifier. MyHomePage({Key key, this.title}) : super(key: key);
^^^
lib/main.dart:23:29: Error: The parameter 'title' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier. MyHomePage({Key key, this.title}) : super(key: key); ^^^^^ Target kernel_snapshot_program failed: Exception
From the original code:
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
make the next changes:
...
MyHomePage({Key? key, required this.title}) : super(key: key);
...
Upvotes: 0
Reputation: 126924
The reason this happens is because with null safety enabled, your non-nullable parameter factor
or key
cannot be null
.
In the function and the constructor, these values might be null
when the function is called without the named parameter: calculate()
or Foo()
. However because the types (int
and Key
) are non-nullable, this is invalid code - they must never be null.
There are essentially three ways of solving this:
required
This is probably the most common solution to this problem and it indicates that a variable has to be set. This means that if we have (notice the required
keyword):
void calculate({required int factor}) {
// ...
}
We indicate that the factor
parameter must always be specified, which solves the problem because only calculate(factor: 42)
et al. will be valid calls of the function.
Another solution is providing a default value. If our parameter has a default value, we can safely not specify the parameter when calling the function because the default value will be used instead:
void calculate({int factor = 42}) {
// ...
}
Now, a calculate()
call will use 42
as the factor
, which is obviously non-null.
The third solution is something that you really want to consider, i.e. do you want to have a nullable parameter? If so, you will have to null check the parameter when using it in your function.
However, it is the way you would most commonly want to solve the Key key
issue because you do not always want to provide a key to your widget in Flutter (note the nullable Key?
type):
class Foo extends StatelessWidget {
const Foo({Key? key}): super(key: key);
// ...
}
Now, you can safely construct Foo()
without providing a key.
Note that the same applies to positional parameters, i.e. they can be made nullable or non-nullable, however, they cannot be annotated with required
and cannot have default values as they are always required to be passed.
void foo(int param1) {} // foo(null) is invalid.
void bar(int? param1) {} // bar(null) is valid.
Upvotes: 237
Reputation: 945
Add a required keyword before the variable in the constructor and also add '?' next to Key.
MyHomePage({Key? key, required this.title}) : super(key: key);
Upvotes: 7
Reputation: 36
Changing the SDK version in pubspec.yaml solves the issues:
environment: sdk: ">=2.1.0 <3.0.0"
Upvotes: 1
Reputation: 4130
If i get this error from the constructor
of a class pointing key
, i add a '?
' mark infront of Key
like this:
const ClassName({Key? key}) : super(key: key);
'?
' means that can be nullable
Upvotes: 17
Reputation: 139
Add requuired function for Eg
required Key key,
required this.id,
required this.name,
required this.code,
required this.img,
required this.price,
required this.promotionPrice,
required this.size,
required this.color,
Upvotes: 13
Reputation: 2595
As additional information to the previous @creativecreatorormaybenot's answer, you can also use positional parameters (no curly brackets) that are mandatory by default, so not nullable.
void calculate(int factor) {
// ...
}
and is called without naming the parameter:
calculate(12);
These kind of parameters can be used on constructors this way:
class Foo extends StatelessWidget {
final String myVar;
const Foo(this.myVar, {Key? key}): super(key: key);
// ...
}
and "can be followed either by named parameters OR by optional positional parameters (but not both)", see doc here: dart parameters
Interesting answer on difference between named and positional parameters: What is the difference between named and positional parameters in Dart?
Upvotes: 11
Reputation: 28996
It's the main reason why non-nullable feature is added to Dart. Since, you're passing Key
to super class, which could be null
, so you want to make sure it's non null. What you can do is either not use the key
at all or provide a default value to it or make it required
. Like:
MyPage({Key key = const Key("any_key")}) : super(key: key);
or make key
required like this:
MyPage({required Key key}) : super(key: key);
Upvotes: 25