Non-nullable instance field '_dio' must be initialized Flutter - flutter

I am using Dio for Json parsing and i have created a class for simple Json parsing and serializing but i am getting the following error
Non-nullable instance field '_dio' must be initialized. (Documentation) Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.
Below is the code for my class
Dio _dio;
final baseUrl = "";
HttpService(){
_dio = Dio(BaseOptions(
baseUrl:
));
}
What might i be doing wrong

Your variable _dio is non-nullable which means it can never be null.
However when you put Dio _dio; it doesn't get a value.
You have 2 options:
Either make it nullable by putting a ? after the type: Dio? _dio;
or make it a late variable late Dio _dio; which means that it will shortly after get a value (hopefully _dio = Dio(BaseOptions(baseUrl:)); will do so) so that it can be treated as "never null" afterwards.
EDIT:
More on that topic: https://dart.dev/null-safety

Related

How to initialize a variable in the constructor?

I'm learning how to use clean architecture and I just started with the repository (appwrite) and used a singleton pattern. Now I want my AuthService class to take a repository and continue.
However I have a problem in this class:
import 'package:appwrite/appwrite.dart';
import 'package:mandi/infrastructure/repositories/appwrite_service.dart';
class AuthService {
final AppwriteService _appwriteService;
AuthService({AppwriteService appwriteService})
: _appwriteService = appwriteService;
Future<void> register(
String email,
String password,
String firstName,
String lastName,
) async {
final Account account = Account(_appwriteService.client);
account.create(
userId: ID.unique(),
email: email,
password: password,
name: '$firstName $lastName',
);
}
}
The constructor gives an error at 'appwriteService' because "The parameter 'appwriteService' 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 just read on this platform that after the ':' comes the initializer field, however, the compiler still complains about it being possibly null.
I don't know how to solve this.
Please try the below code bloc :
if you want name constructor you have to give required
AuthService({ required AppwriteService appwriteService})
: _appwriteService = appwriteService;
Without named constuctor you can use like :
AuthService(AppwriteService appwriteService)
: _appwriteService = appwriteService;

Why does it keep saying initialize variable?

Below is the code I wrote. I need to initialize a variable called verificationID for later use. But I keep getting a red squiggly line with the text -
Final variable verificationID must be initialized
Non-nullable instance field vdi must be initialized.
Is this not how you initialize - final [datatype] [name]
I am brand new to flutter and could use any help!
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
enum NumberVerification {
SHOW_MOBILE_FORM_STATE,
SHOW_OTP_FORM_STATE,
}
class LoginScreen extends StatefulWidget {
final String verificationID;
String vdi;
#override
_LoginScreenState createState() => _LoginScreenState();
}
All variables in Dart are getting the value null if nothing else are specified. This is a problem in your case since both verificationID and vdi are specified as non-nullable types (no ? after the type name). So Dart complains about this problem.
Another problem is your final variable which also should be provided a value since this is a read-only variable which can only be assigned a value when initialized.
You therefore need to do:
Change the types to allow null.
Or, provide default value other than null.
Or, make a constructor of your class which gives values to your variables. These values can come from parameters to the constructor.
Because flutter and dart language are null safety. It means you should initialize your variables, and there will be no error regarding this in runtime. So when you write dart codes you must initialize them as follows:
1- In some cases you can init value directly as follows:
final String verificationID = 'value';
2- Or you can get the value from constructor of class.
final String verificationID;
LoginScreen(this.verificationID);
3- And also, you can declare that you will initialize the value later. This way you guarantee that you will initialize the value, so you should use it wisely.
late String verificationID;
verificationID = 'value';
4- Lastly, you may declare a value as nullable. This way, you don't need to initialize the variable directly.
String? verificationID;

Late variable in Dart

I'm new to use Websocket in Flutter.
So I was reading some post (https://blog.logrocket.com/using-websockets-flutter/) to understand how to use websocket, and I have some question.
The guy in this post declare _etheWebsocket,_btcWebsocket variables as late as below.
class CoinbaseProvider {
late final WebSocketChannel _ethWebsocket;
late final WebSocketChannel _btcWebsocket;
CoinbaseProvider()
: _ethWebsocket = WebSocketChannel.connect(
Uri.parse('wss://ws-feed.pro.coinbase.com'),
),
_btcWebsocket = WebSocketChannel.connect(
Uri.parse('wss://ws-feed.pro.coinbase.com'),
);
But why not just declare without late like below??
What is the reason have to declare WebsocketChannel as late.
class CoinbaseProvider {
final WebSocketChannel _ethWebsocket = WebSocketChannel.connect(
Uri.parse('wss://ws-feed.pro.coinbase.com'),
);
final WebSocketChannel _btcWebsocket = WebSocketChannel.connect(
Uri.parse('wss://ws-feed.pro.coinbase.com'),
);
CoinbaseProvider();
Short explanation
You declaration looks better, since in your context you have the values to the variables _ethWebsocket and _btcWebsocket
But why? a dive into late and null-safety features
What's null-safety in Dart? This is a recent released feature (2021) that in summary it prevent us, developers, to create variables of a type that can be implicity null, then avoiding runtime errors as TypeError: can't read property '...' of null
But in summary, unlike before null-safety, now:
All variables can't be null implicity by default!
Show me the code
Before null-safety:
This snippet below is a valid statement before null-safety, this variable can be a String 'hi!' or null
String myVariable; // null by default
After null-safety:
The same snippet now is a invalid statement, the variable should be initialized because her can't be null
String myVariable; // Error!
To declare a variable that can be null by default, as like before the null-safety update you should write as:
String? myVariable; // Note the '?' after the Type
But what if you want to declare variable without the value and without explicitly declaring that it can be null?
The answer is late!
late is just a Dart language feature to allow you say to the compiler: "Hey, I don't have the value of this variable right now, but I promise you I'll set her somewhere else before using it, so her can't be null"
late String myVariable;
print(myVariable); // Throws an LateInitializationError instead of printing 'null'
Conclusion
Given these features and the null-safety use them to avoid wasting time with null pointer exceptions and improve your code typing.
So there's no right or better way, all depends on the context.
For the exact example you used I would say they are identical, and your version would be better. My guess it that they made it like that, is to allow adding additional constructors, maybe like
CoinbaseProvider.customUrl(String eth, String btc)
: _ethWebsocket = WebSocketChannel.connect(
Uri.parse(eth),
),
_btcWebsocket = WebSocketChannel.connect(
Uri.parse(btc),
);

Uncaught LateInitializationError: Field 'deviceToken' has not been initialized

Error: Uncaught LateInitializationError: Field 'deviceToken' has not been initialized.
Not sure what went wrong here.
late String deviceToken;
var registerRepo = GoogleSignInRepo();
FirebaseAuth auth = FirebaseAuth.instance;
Future<String> gettoken() async {
final String? token = await FirebaseMessaging.instance.getToken();
return token!;
}
#override
void initState() {
gettoken().then((value) {
deviceToken = value;
});
super.initState();
}
Well the error pretty much tells you the problem:
Error: Uncaught LateInitializationError: Field 'deviceToken' has not been initialized.
Flutter is null-safe, therefore if you define a variable you need to assign a value to it since the value by definition is not allowed to be null. Keep in mind that the late keyword only tells you that the variable will be initialized at runtime instead of compile time.
This means that some other part of your code probably accesses deviceToken before it was initialized in your Future.
You can solve it like this:
// Assign a value (empty string in this case).
String deviceToken = "";
Another solution would be to make your field nullable and this is probably the better solution in your case.
// Null is a valid value and will not cause a error.
String? deviceToken;
Or: Make sure the field was initialized before you access it.
For further reference this article might help you out:
https://dart.dev/null-safety/understanding-null-safety

What is the difference between using `late` keyword before the variable type or using `?` mark after the variable type it in the Flutter?

I think in new Dart rules the variables can not be declared/initialized as null. So we must put a late keyword before the variable type like below:
late String id;
Or a ? mark after the variable type like below:
String? id;
Are these two equal Or there are some differences?
A nullable variable does not need to be initialized before it can be used.
It is initialized as null by default:
void main() {
String? word;
print(word); // prints null
}
The keyword late can be used to mark variables that will be initialized later, i.e. not when they are declared but when they are accessed. This also means that we can have non-nullable instance fields that are initialized later:
class ExampleState extends State {
late final String word; // non-nullable
#override
void initState() {
super.initState();
// print(word) here would throw a runtime error
word = 'Hello';
}
}
Accessing a word before it is initialized will throw a runtime error.
when you use late keyword you can't let variable uninitialized when you called it with ? allows to you let variable uninitialized when you create it and call it
Null safety rules doesn't mean you can't use null. You can, but you should indicate that a variable might have the value null, by add "?" to its type declaration.
By use keyword late you indicate that variable has a non-nullable type, is not initialized yet, but will be initialized later.
Exception is thrown if try to acсess value of late variable before initialization.