What is this operator "?." in Dart? - flutter

i work with flutter framework
this part of the code use a operation "?." but idont understand
if (state is WeatherLoaded) {
final weather = state.weather;
final themeBloc = BlocProvider.of<ThemeBloc>(context);
themeBloc.dispatch(WeatherChanged(condition: weather.condition));
_refreshCompleter?.complete();
_refreshCompleter = Completer();
all code this link

The best way to demonstrate this is a simple example.
I have an object SomeObject with one method username.
I have made 2 instances of it:
aeonObject which is not null
someOtherObject which is null
class SomeObject {
String username() => "aeon";
}
void main() {
final aeonObject = SomeObject();
print(aeonObject.username());
SomeObject someOtherObject;
print(someOtherObject.username());
}
If I execute this snippet you'll see the following output.
The program will crash because we tried to execute a method on a null reference.
dart lib/main.dart
lib/main.dart: Warning: Interpreting this as package URI, 'package:sample/main.dart'.
aeon
Unhandled exception:
NoSuchMethodError: The method 'username' was called on null.
Receiver: null
Tried calling: username()
However if I call the print statement with the ?. aka Conditional member access operator.
print(someOtherObject?.username());
We instead get.
null

Check this link: Language tour
?.
Conditional member access
Like ., but the leftmost operand can be null; example: foo?.bar
selects property bar from expression foo unless foo is null (in which
case the value of foo?.bar is null)

Related

Can't assign non-nullable type to a nullable one

error: The argument type 'Future<List<GalleryPictureInfo>>' can't be assigned to the parameter type 'Future<List<GalleryPictureInfo>>?'.
Is this Dart Analysis or me? The project still compiles.
Upd. Added code example
FutureBuilder<List<GalleryPictureInfo>>(
future: derpiService.getListOfImages(),
//other code
);
#override
Future<List<GalleryPictureInfo>> getListOfImages(arguments) async {
List<GalleryPictureInfo> listOfImages = [];
var searchImages = await getSearchImages(tags: tags, page: page);
//adding images to List
return listOfImages;
}
It's something with FutureBuilder actually. I should've mention this.
Upd. "Fixed" with // ignore: argument_type_not_assignable
Looks like a problem with Dart Analysis for now
Upd. Error
It actually is an error which is pretty self explanatory.
The acutal error comes because of null safety in dart.
For ex:
void main(){
var number = getNumber(true);
int parsedNumber = int.parse(number);
print(parsedNumber);
}
String? getNumber(boolean value) {
if (value){
return null;
} else return "1";
}
So here, getNumber function either returns null or "1" depending upon the value of value variable. So, number variable's type is String?.
But the error shall arise in the next line when you try to call int.parse(). int.parse function takes an argument which should be a String but the value passed in the function is of type String?. So if we pass null in int.parse it shall throw an error.
That's why Dart analysis makes it easier to identify such cases by telling us that the value can be null and it might throw.
However the code depends upon your actual code of your project. It says that you are passing Future<List<GalleryPictureInfo>>? which is of nullable type to a function which requires Future<List<GalleryPictureInfo>>. So, before passing the value you might want to check if the value you are passing is not null.
If you are sure that the value can never be null then if for ex: if you are passing a variable called value, you might wanna try someFunctionWhereYouPassValue(value!)
That ! means that you are sure that the value will never be null.
For more details about null safety you can see:
https://dart.dev/null-safety/understanding-null-safety

How to deal with information that arrives null? - NoSuchMethodError

I'm getting null information from a web api. If a single information is null, the error will occur:
Error: Exception: NoSuchMethodError: '[]'
Dynamic call of null.
Receiver: null
Arguments: ["address"]
I declared this information in the model like this:
final String? address;
..
address: json['data1']['data2'][0]['data3']['address'][0]
I tried to do something like:
address: json['data1']['data2'][0]['data3']['address'][0].isEmpty
? ''
: json['data1']['data2'][0]['data3']['address'][0],
But it does not work.
I appreciate if anyone can help me analyze it!
The only thing you can do is to anticipate the null values and handle each case as needed.
For instance, if a null value is not accepted at all, you could wrap the code in throw ... catch statement then throw an error -- e.g.Missing Data and handle that error.
If having a null value is fine, you can use the null aware operator ? (or a nested if-statements if you prefer that). For example, assuming the value is a String, you could do something like this:
final String? myValue = json['data1']?['data2']?[0]?['data3']?['address']?[0];
Though, keep in mind if you're accessing a list by index, you still can get a RangeError if the index is out of range or if the list is empty. In such case you may need to split the process in a separate method and inspect each part separately such as:
String? extractValue(Map<String, dynamic> json) {
final firstList = json['data1']?['data2'];
if (firstList is List && firstList.isNotEmpty) {
final innerList = firstList[0]['data3']?['address'];
if (innerList is List && innerList.isNotEmpty) {
return innerList[0];
}
}
return null; // or return a default value or throw an error
}
You can handle such arguments ( arguments that give you null value) like this.
Let's say there's a variable a and there's a possibility that it'll give a null value, you can give it a default value.
For example:
There is a variable 'a', which is your data source.
String name = a ?? "This is not a null value";
The ?? would check if the value is null or not. If it's null, it would assign the value that you provided, otherwise it would keep the existing one.

How to use the Null assertion operator with instance fields

I'm having trouble understanding how to type promote an object's field if it is nullable. Let's say I had the following Comment class and tried to access its one nullable field:
class Comment {
final String? text;
Comment(this.text);
}
void main() {
final comment = Comment("comment");
if (comment.text!= null) {
String text = comment!.text;
}
}
The Dart compiler would give me an error for trying to assign a nullable variable to a non-nullable variable. From what I've gathered from looking into this topic, it's impossible to have type promotion with instance variables because instance variables can be modified which can then break the sound null-safety. I've seen the Null assertion operator (!.) being used in these circumstances, however it doesn't seem to work with fields, only with methods.
With dart null-safety, how should I go about assigning a nullable field such as String? to a non-nullable variable (String). To the same effect, how should I go about passing a nullable field to a function that requires a non-null argument.
You can fix it in different ways:
Use local variable (recommended)
final local = comment.text; // <-- Local variable
if (local != null) {
String text = local;
}
Use ?. and provide a default value
String text = comment?.text ?? 'Default value';
Use Bang operator !
if (comment.text != null) {
String text = comment.text!; // <-- Bang operator
}
Note: Bang operator can result in a runtime error if the text was null.

Error while using Flutter with Riverpod and null safety

I am using Flutter with Riverpod and null safety for the first time and I have the following provider that should return ImageProfile or null.
final myProfileImageProvider = Provider.autoDispose.family<ProfileImage?, int>(
(ref, index) {
final images = ref.watch(editMyProfileViewModelProvider.state).images;
if (index < images.length) {
return images[index];
}
return null;
},
name: 'myProfileImageProvider',
);
I am reading the provider inside a function like this:
final profileImage = context.read<ProfileImage>(myProfileImageProvider(profileImageIndex));
But I am getting the following compiler error.
The argument type 'AutoDisposeProvider<ProfileImage?>' can't be assigned to the parameter
type 'ProviderBase<Object, ProfileImage?>' because 'ProfileImage?' is nullable and 'Object'
isn't.
Notice that inside a function, I can't use watch or useProvider. I must use context.read. Please note that useProvider() does solve the problem but can't use it inside a function. The problem is when reading the provider inside a function.
Any body out there know the answer to this?
I appreciate any help.
Thanks

Dart, Identifier with exclamation mark in the back

Recently I have been developing mobile aplication with flutter, when I looking at the source code for TickerProvider I see these lines:
mixin SingleTickerProviderStateMixin<T extends StatefulWidget> on State<T> implements TickerProvider {
Ticker? _ticker;
#override
Ticker createTicker(TickerCallback onTick) {
...
_ticker = Ticker(onTick, debugLabel: kDebugMode ? 'created by $this' : null);
return _ticker!;
}
...
}
I'm interested with this line:
return _ticker!;
I have seen boolean identifier with exclamation mark in the front meaning that it will return the opposite value of it, but I never see this one. Can someone tell me what this does?
It's part of the null safety that Dart have.
You can read about it here
If you’re sure that an expression with a nullable type isn’t null, you can add ! to make Dart treat it as non-nullable
Example:
int? aNullableInt = 2;
int value = aNullableInt!; // `aNullableInt!` is an int.
// This throws if aNullableInt is null.
For betrer undestanding (by analogy with the action of the algorithm itself).
This operator acts as the following inline internal function (at least similarly):
T cast<T>(T? value) {
if (value == null) {
throw _CastError('Null check operator used on a null value');
} else {
return value;
}
}
P.S.
Forgot to add.
Based on the error messages that are generated at runtime, we can conclude that this operator is called the Null check operator, which may mean that it checks the value for null and throws an exception if the value is null.
No magic!