in the code example i found something like this:
String? selectedNotificationPayload;
which means the question mark next to the type of the String variable
It means the type is NullableString. This works for Flutter 2 and above due to null-safety in dart. It basically means the value stored can be a null.
So, String? foo; allows null but String bar; does not allow null.
https://dart.dev/codelabs/dart-cheatsheet
https://dart.dev/null-safety
Related
This question already has an answer here:
Multiple types for a single variable (parameter/return type)
(1 answer)
Closed 11 days ago.
I am new to flutter. I want to know can I set a variable type String or int? In typescript we can do like let a: string | number. Is it possible to achieve something like this in dart language? I don't want to set the type dynamic since it all accept kind of any type and won't throw any error if I use other types than String or int.
You can't do this in dart. You can make it dynamic. You can implement some type of enum or class that takes a dynamic variable and checks if it is String or int. Or you can separate your variable into two. Another useful dart feature is the is operator.
You can do:
if(myVar is int) or
if(myVar is String)
How to fix this? Error Message: The method 'compareTo' can't be unconditionally invoked because the receiver can be 'null'.
Try making the call conditional (using '?.') or adding a null check to the target ('!').
Second Error: The argument type 'Object?' can't be assigned to the parameter type 'Object'.
How to fixed it?
It looks like you lack basic understanding about null safety features.
String? basically means that it's a String that can be null. This can be done with any type. A question mark ? at the end of the type name makes it nullable, and if it isn't there it can't be null.
The language is designed in such a way that you can't assign any objects that are nullable to variables that aren't or use methods of objects that might be null.
There are several ways to handle this.
1) don't make them nullable in the first place.
In your example, whatever the object is, it must have some field declared as String? name. Just remove the ? if possible. There's a good chance it will make other errors pop up, but it should be solvable, at least in the case where you don't allow it to be null. If for whatever reason you need it to be nullable this is not a solution.
2) tell the compiler that you are sure it's not null in this situation
This is done by adding ! at the end of the variable. In your example that would be:
b.name!.compareTo(a.name!)
This is probably the easiest solution but the program will throw errors at runtime if they do happen to be null
3) provide a fallback value using ??
?? basically is an operator that returns the left side if it's not null and otherwise the right side. You can use this to your advantage to provide fallback values. In your example you could do:
(b.name ?? '').compareTo(a.name ?? '')
This way it takes empty string in case the name is missing. This would be a safer option compared to option 2.
4) conditional calling using ?.
Maybe not applicable in your situation but good to know anyway. Let's say some class A has the method getName and you have an object a of type A? and this code:
String? b = a.getName();
this is not allowed because a can be null. But you can write this:
String? b = a?.getName();
This basically mean that it executes getName() and assigns it to b when a is not null or just assigns null otherwise, which is possible because b is allowed to be null here. Therefore, this is NOT possible
String b = a?.getName();
Now b is defined as not being nullable and since the assignment possibly can provide null you are not allowed to.
Hello good folk of stack overflow, teaching myself flutter and have come across null safety.
I believe I 'understand' the difference between making a variable nullable and telling dart I will initialise later. But is there a correct way to do it?
In what instance would you choose late over making a variable nullable?
Consider the small class I have below, I've chosen to use the late method (admittedly I don't really know why) Would you chose this same method or should I be making the variables nullable?
Thanks!
class Quote{
late String text;
late String author;
Quote(String text, String author){
this.text = text;
this.author=author;
}
}
There is also a third solution and forth (done in two ways) solution here.
You can add a non-null default value to the field.
String text = '';
But I would go here with initializing the fields directly in the constructor argument list.
class Quote {
String text;
String author;
Quote(this.text, this.author);
}
...or using a constructor initializer list:
class Quote {
String text;
String author;
Quote(String text, String author)
: text = text,
author = author;
}
Using the forth solution (second and third code snippet) you can also make those fields final and the constructor constant.
Lastly, quoting the documentation Classes - Language Tour | Dart:
Instance variables can be final, in which case they must be set exactly once. Initialize final, non-late instance variables at declaration, using a constructor parameter, or using a constructor’s initializer list (...)
If you need to assign the value of a final instance variable after the constructor body starts, you can use one of the following:
Use a factory constructor.
Use late final, but be careful: a late final without an initializer adds a setter to the API.
You mentioned the answer in the question too. If your business logic requires to check if a value is null use nullable variable and if you want some definite value then use late. For example you may not know if you will get a response from an api as expected. So better to define as nullable.
I just started learning Dart. There is some problem when I am creating a null variable. When I type
String someVar;
it throws an error but when i type
dynamic someVar;
it doesn't. I tried doing alternative methods mentioned in Dart's doc but even those methods do not seem to work until i have a dynamic var type. Can anyone tell me what is it?
Dart has a feature called null safety, so when you define something which might have a null value, you have to use ?.
In your code above, try something like String? somevar;
If you are going to initialize the variable later, then define late String somevar;
If you have null safety on String someVar; will give you an error because it cannot be null.
If u want a variable to be a nullable string, use String? someVar.
Try avoiding the use of dynamic because it will allow for the type to not be fixed. This can potentially cause the accidental assigning of a value with a type you are not expecting.
I have few questions with regards to the null safety feature offered by Flutter/Dart.
Is it mandatory to make use of the null safety feature for flutter projects?
If I don't make use of the null safety feature, will I still be able to make use of all the existing and latest flutter widgets, with all the latest functionality they have got to offer? What I mean to say is, is there any specific functionality that is only available when the null safety feature is enabled.
What would be the major disadvantages, I could encounter, apart from the null check, if I don't make use of the null safety feature for the flutter projects?
Even if the code is correct, I find that the null safety feature would keep throwing the null check operator error, which is very annoying.
Could anyone please help with answering my queries, as I find this null safety to be very confusing and annoying. I did go through few videos but still, I'm not convinced.
Thank you so much for your help in advance.
Null safety can be overridden
Yes, you should still be able to make use of the new flutter widgets.
If you use don't null-safety, it will be slower
This is more like a statement than a question
Understanding Null Safety.
Is it mandatory to make use of the null safety feature for flutter projects?
No, you can still use the previous SDK constraints to not comply with NULL safety rules
environment:
sdk: ">=2.11.0 <3.0.0"
If I don't make use of the null safety feature, will I still be able to make use of all the existing and latest flutter widgets, with all the latest functionality they have got to offer? What I mean to say is, is there any specific functionality that is only available when the null safety feature is enabled.
Yes provided you set the environment as mentioned above or you can also specify at the top of your Dart file to disable null checks for that file.
// #dart=2.9
What would be the major disadvantages, I could encounter, apart from the null check, if I don't make use of the null safety feature for the flutter projects?
Note that eliminating null is not a goal. There’s nothing wrong with null. On the contrary, it’s really useful to be able to represent the absence of a value. Sometimes indicating absence is really important. It is not null that is bad, it is having null go where you don’t expect it that causes problems. So to avoid such crashes Dart migrated to Sound NULL Safety.
Even if the code is correct, I find that the null safety feature would keep throwing the null check operator error, which is very annoying.
You can definitely make some types NULL with the handy ? null-aware operator. For eg, you can make your String as String? provided indicating absence is really important and it won't cause problems in the future program flow.
Adding ! (null assertion operator )after any expression is equivalent to saying that "Hey Dart ! trust me that this value will never be null".
Initially, it might trouble you a lot. But remember, it's worthwhile migrating your apps to Sound Null Safety.
Further Reading -
https://dart.dev/null-safety
Why NULL Safety ?
example:
class Animal {
Dog dog;
}
class Dog{
String name;
}
Operator "!":
If you allow it to be null and allow it to throw an exception.
main(){
Animal animal = Animal();
print(animal.dog!.name); // throw exception dog is null
}
Operator "?"
If you want it will do nothing if the current parameter is null
main(){
Animal animal = Animal();
print(animal.dog?.name); // output emplty
}
You can give a replacement value of the parameter if the current value is null
main(){
Animal animal = Animal();
print(animal.dog?.name ?? "The kiki"); // output "The kiki"
}
The function required not null
fun getName(String name){
print(name);
}
main(){
String? name = null;
getName(name); // throw an exception because the required the name argument is not null
}
The function allows null
fun getName(String? name){
print(name);
}
main(){
String? name = null;
getName(name); // output null
}
Null safety in the Constructor
Use required operator
class Animal {
String? name;
String age;
Animal({this.name,required this.age}); // The age argument not allowed to be null so you must add the required operator first
}
or use positional arguments constructor
class Animal {
String? name;
String age;
Animal(this.age, {this.name}); // age is positional argument
}
or use default value constructor
class Animal {
String? name;
String age;
Animal({this.name, this.age = "18" }); // age is positional argument
}