Its a general question. Not coding related. Everywhere I follow flutter tutorials I see the simple variable declarations. But when I write the same code (I think because of updating) it requires to add late modifier.
late modifier can be used while declaring a non-nullable variable that's initialized after its declaration. Declaration of variables that will be initialize later is done using late modifier.
That's what I read on the google.
Why it is necessary to declare non-nullable variables. Vscode always underlines the variable showing error. But ate modifier. What do we need to change when we change variables to late. Cause its making following tutorials very difficult. set state is not helping.
This is because of null safety in Dart. There are a lot of guides out there written before null safety was introduced.
It is ok to declare a class member as nullable with the ?, so this is valid, and means that i can have the value null, therefore it is allowed without initialising its value:
int? i;
If you don't use the ?, you can still declare a member, but you have to assign a value to it, this is also valid:
int i=1;
But this will be invalid, since you say that i can't be null, and you do not assign a value to it:
int i;
And here comes the late keyword. By using this you "promise" Dart, that you will initialise this value later, for example in an initState method like this:
class MyWidget extends StatefulWidget {
const MyProfile({Key? key}) : super(key: key);
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late int _i;
#override
void initState() {
super.initState();
_i = 1;
}
You have to keep this "promise", otherwise you will get a runtime error.
Another option is that you create a constructor for the class that has required members, it will ensure that these values can't miss in any instance created, so Dart is ok with it:
class MyClass {
int i;
MyClass({required this.i});
}
In this last example, if you omit required keyword, you will get an error, because i is not nullable, and if it is not required by the constructor, it could be null. Still, it will work without required, if you make i nullable by declaring it like int? i;.
the late modifier is part of the new null-safety by dart it's used to tell the compiler to treat this variable as non-nullable and will be initialized later without it the compiler will treat the variable as nullable and give error
late String name;
#override
void initState() {
super.initState();
name = "example";//the compiler will not see this to know that you have initialized the variable
}
#override
Widget build(BuildContext context) {
if(name=="example"){
...
}
}
Related
so I have a GetxController, like the following:
class ExampleController extends GetxController {
late TextEditingController textController;
#override
void onInit() {
textController = TextEditingController();
super.onInit();
}
}
this piece of code will work very fine, but as I know, using the late keyword is not recommended use, and removing it, in this case, will cause a dart analyzer null safety lint:
Non-nullable instance field 'emailController' must be initialized.
Try adding an initializer expression, a generative constructor that initializes it, or mark it 'late'.
so is their better options, or ways to do the same without using late or marking the TextEditingController() nullable?
I'm new to Flutter development and trying to learn.
I want to create a model with a constructor, one of which contains a field of type DateTime which is optional.
I tried by making it like this:
import 'package:equatable/equatable.dart';
class Customer extends Equatable {
final int indexs;
final DateTime apply_date;
Customer({
required this.indexs,
this.apply_date,
});
#override
List<Object?> get props => throw UnimplementedError();
}
But an error message appears like this
The parameter 'apply_date' can't have a value of 'null' because of its
type, but the implicit default value is 'null'. Try adding either an
explicit non-'null' default value or the 'required' modifier.
I've tried to learn from this and this reference, and what I understand there are 3 ways:
Include required modifiers
Set initial value
Nulllabel parameter / Fill it with (?) => I don't understand this
So how to do this properly?
I don't want to make this field required, because it's optional.
I also don't know what to fill if I want to fill it with an initialvalue.
Thank you!
Making the attribute nullable is the same as making it an optional attribute.
You can do that by adding ? behind the attribute's type.
class Customer extends Equatable {
final int indexs;
final DateTime? apply_date;
Customer({
required this.indexs,
this.apply_date,
});
#override
List<Object?> get props => throw UnimplementedError();
}
I want to have a StatefulWidget where I can pass the initial value for a non-nullable member of the widgets State from the widgets constructor.
My current solution (see below) seems to be not ideal, I see two problems with it:
The initial value has to be saved in the widget itself before passing it to the state.
The member in the sate has to be marked as late since it can only be set after initialization.
Is there a better way to initialize a StatefulWidget's state non-nullable member from a value passed to the widget constructor?
My current implementation:
class MyWidget extends StatefulWidget {
final String text;
const MyWidget({Key? key, required this.text}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late String text;
#override
void initState() {
text = widget.text;
super.initState();
}
#override
Widget build(BuildContext context) {
return Text(text);
}
}
(Not shown here, but later the text member should be changeable, that's why it is in the State)
hey there your code seems good.
but the better way is using bloc to pass and receive data.
any way . its not necessary to pass and fill data in initstate and _MyWidgetState .
you can receive your data directly in build widget As you wrote (widget.text)
here is some good things for avoid nullable
https://codewithandrea.com/videos/dart-null-safety-ultimate-guide-non-nullable-types/
You could use the constructor of State like this: _MyWidgetState(){ text=widget.text; }. The constructor will certainly be executed before initState and build methods.
When a instance function being declare Static, does that mean that it can't return a new instance of another object?
Aren't the purpose of the Static keyword is to save the memory, does that mean when i call the static member, it had to return for me the EXACT object ?
class Provider extends InheritedWidget {
final bloc = Bloc();
bool updateShouldNotify(_) => true;
Provider({Key key, Widget child}) : super(key: key, child: child);
static Bloc of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<Provider>().bloc;
}
}
class SignUp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// This is not the same object
final bloc = Provider.of<Bloc>(context);
}
class Login extends StatelessWidget {
#override
Widget build(BuildContext context) {
// This is not the same object
final bloc = Provider.of<Bloc>(context);
}
Once function is declared static, that means it is no longer "instance" function, but rather class function.
Declaring function static means that you no longer have access to instance (i.e. this). This is just function aliased by the class it is declared in.
Static function can return anything, including new instances of classes, where it is declared.
Static function will not help you to save memory.
My assumption though (I might be wrong) is that static function is a little bit easier for compiler to compile as it does not take part in polymorphism.
Everything from Alex above is correct.
I just want to point the most important differences you should no:
It is not related to any object, and so it can be called directly from the class.
In Java and maybe other languages polymorphic rules no longer work as expected. For this many people do use the Singleton-Pattern, which itself is based on a static function.
Further reading:
https://en.wikipedia.org/wiki/Static_(keyword)
https://en.wikipedia.org/wiki/Singleton_pattern
https://www.javatpoint.com/static-keyword-in-java
https://www.geeksforgeeks.org/static-methods-vs-instance-methods-java/
In general you should try doing some own research before asking questions here, and so make questions less random ;)
I have a stateless widget and while writing the code I am using a non-final field in the stateless widget and the ide keeps giving me warning that all the fields in stateless widget should be final
But I don't understand why having a non-final field in stateless widget be a problem.
I think it should be perfectly fine to have non-final field because there could be a field that we don't want to modify later but this field can only be initialized inside the constructor function so, for that you need to use non-final field
example:
class Temp extends StatelessWidget {
final int a;
final int b;
int c;
temp({this.a, this.b}) {
this.c = this.a + this.b;
}
#override
Widget build(BuildContext context) {}
}
In the above widget, I can't make c as final because it is initialized inside the constructor function even though I have no plans to change the c variable in the future.
If having a non-final field in a Stateless widget is not a good Idea then How to handle the above situation.
Note: I cannot use the Constructor() : [initialization] {} because the initialization can involve the function or loops
StatelessWidget class A widget that does not require mutable state, so the class is marked as #immutable, Dart language do the best to fix your errors, so "final" keyword will just warn you about that but will not stop the compiling, you can use your code normally without final keyword if you are sure it will initialized one time and not change again at run-time ..
and this is the main reason to have 2 keywords (final, const) for define constants in Dart language
Both final and const prevent a variable from being reassigned.
const value must be known at compile-time, const birth = "2020/02/09". Can't be changed after initialized
final value must be known at run-time, final birth = getBirthFromDB(). Can't be changed after initialized
You can use initialization even for function invocation.
here is an example:-
class SumWidget extends StatelessWidget {
final int sum;
static getSum(List<int> items) {
int perm = 0;
for (var value in items) {
perm += value;
}
return perm;
}
SumWidget(List<int> roles) : this.sum = getSum(roles);
#override
Widget build(BuildContext context) {}
}
but function must be static because The instance member can't be accessed in an initializer.