Flutter nullsafety: conditional List position - flutter

If I am not sure a list is null or not, I could do
final something = myList?[0].property;
What if I knew myList existed but was not sure there is an element in it?
Do I need to manually check that isNotEmpty?
final something = myList[0]?.property;
says The receiver can't be null, so the null-aware operator '?.' is unnecessary.

You need to define your list to be nullable.
e.g.:
List<myObject?> myList = [myObject(), null, null, myObject()]
// then error is not shown
final something = myList[0]?.property;
Example
void main() {
List<int?> list = null;
for (var i = 0; i< list.length; i++ ) {
print(list[i]?.isEven);
}
// Error: The value 'null' can't be assigned to a variable of type 'List<int?>' because
// 'List<int?>' is not nullable.
// - 'List' is from 'dart:core'.
// List<int?> list = null;
List<int?> list2 = [null, 2, 1, 3, null];
for (var i = 0; i< list2.length; i++ ) {
print(list2[i]?.isEven);
}
// no error
List<int?> list3 = [];
print(list3[5]?.isEven);
//no error
}

Yes. you need to check it is empty or not.
if myList exist and not null
late List<dynamic> myList;
myList = [];
if (myList.length > 0){
}
if myList can be null
late List<dynamic>? myList;
if (myList != null && myList!.length > 0) {
}

Related

Flutter: How can I store another list in a value of a list - error "type 'UserForPosts' is not a subtype of type 'Iterable<dynamic>of 'iterable'

I have a list and I want to save another list in a value of this list, but I get the error:
Flutter: How can I store another list in a value of a list - error "type 'UserForPosts' is not a subtype of type 'Iterableof 'iterable'
Here is my Code:
var userInformationSnap = await FirebaseFirestore.instance
.collection('users')
.where('__name__', whereIn: aUserIDOnly)
.get();
var userInformationSnapList = userInformationSnap.docs.map((d) =>
UsersForPosts.fromJson(d.data())).toList();
for (var i = 0; i < eventsWithoutUserData.length; i++) {
for (var j = 0; j < userInformationSnapList.length; j++) {
if (eventsWithoutUserData[i].userID == userInformationSnapList[j].UserID) {
eventsWithoutUserData[i].userInformation.addAll(userInformationSnapList[j]);
}
}
}
Error - "type 'UserForPosts' is not a subtype of type 'Iterable
dynamic of 'iterable'"
Yes, like Anis Alibegić said try tor replace addAll. with add. like this:
for (var i = 0; i < eventsWithoutUserData.length; i++) {
for (var j = 0; j < userInformationSnapList.length; j++) {
if (eventsWithoutUserData[i].userID == userInformationSnapList[j].UserID) {
eventsWithoutUserData[i].userInformation.add(userInformationSnapList[j]);
}
}
}
return eventsWithoutUserData;

The method 'add' can't be unconditionally invoked because the receiver can be 'null'

I'm trying to handle some data for a flutter application, however I am getting the following error on my code:
The method 'add' 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 ('!').
Map<String, List<SourcefulListing>> sortedSkills = {};
QuerySnapshot listingSnapshot = await listingsRef.get();
List<SourcefulListing> listings = [];
for (int i = 0; i < listingSnapshot.docs.length; i++) {
listings.add(SourcefulListing.fromJson(
listingSnapshot.docs[i].data() as Map<String, dynamic>));
}
for (String skill in skills) {
for (SourcefulListing listing in listings) {
if (listing.selectedSkill == skill) {
if (sortedSkills[skill] == null || sortedSkills[skill] != []) {
sortedSkills[skill] = [listing];
} else {
sortedSkills[skill] = sortedSkills[skill].add(listing);
}
}
}
}
Basically I have a Map with Strings as key and List for the values. The for each loop should add the SourcefulListing object to the map, however there is an error on the .add method.
Any help would be much appreciated.
Try this,
Map<String, List<SourcefulListing>> sortedSkills = {};
QuerySnapshot listingSnapshot = await listingsRef.get();
List<SourcefulListing> listings = [];
for (int i = 0; i < listingSnapshot.docs.length; i++) {
listings.add(SourcefulListing.fromJson(
listingSnapshot.docs[i].data() as Map<String, dynamic>));
}
for (String skill in skills) {
for (SourcefulListing listing in listings) {
if (listing.selectedSkill == skill) {
if (sortedSkills[skill] == null || sortedSkills[skill] != []) {
sortedSkills[skill] = [listing];
} else {
sortedSkills[skill]?.add(listing); // changes made here
setState(() {}); // update ui
}
}
}
}
Null Safety : https://dart.dev/null-safety

Dart: CloudFirestore: Firebase -> How to pass firestore query operator as variable Query<T>.where(key, operator, value)

Firestore with Dart requires query operators to be passed as objects.
Docs: https://firebase.google.com/docs/firestore/query-data/queries
Ex Dart:
.where("key", isEqualTo: value)
Ex Go:
.where("key", "==", value).
In the case of go, passing a string "==" as the query operator is pretty straight forward.
For dart, i am trying to figure out how to store isEqualTo: as a variable, to then pass into the function.
Ok here is my code. Any help is really appreciated thank you!
Here is the DataModel
class FirestoreQueryModel extends Equatable {
//Variables
final String property;
final FirestoreOperatorEnum operator;
// This is the value where i want to store the list of operators
final dynamic value;
}
Here is the current repository
class CustomerRepository{
late Query golbalQuery
Stream <List<CustomerModel>> dynmamicCollectonStream(List<FirestoreQueryModel> queryList,) { //If query list is null, do not apply where clause
if (queryList.isEmpty) { return collectionRef().snapshots().map((doc) {var returnedList = doc.docs; var mappedList = returnedList.map((doc) => CustomerModel.fromDocument(doc)).toList();
return mappedList;
});
} else {var count = queryList.length; CollectionReference cRef = collectionRef();
for (var i = 0; i < count; i++) { golbalQuery = cRef.where(queryList[i].property, isEqualTo: queryList[i].value); }
var list = golbalQuery.snapshots().map((doc) { var returnedList = doc.docs; var mappedList = returnedList.map((doc) =\> CustomerModel.fromDocument(doc)).toList(); return mappedList; }); return list; } }}
In the for loop, where we convert the data model to a where clause I currently have hardcoded isEqualTo:
The goal is to convert
for (var i = 0; i < count; i++) { golbalQuery = cRef.where(queryList[i].property, isEqualTo: queryList[i].value); }
to
for (var i = 0; i < count; i++) { golbalQuery = cRef.where(queryList[i].property, qyeryList[i].operator, queryList[i].value); }

How to type-cast a dynamic list to a multi-dimensional typed list in dart?

If, I have List<dynamic> dynamicList which is actually List<List<double>> but if I try to cast it using,
dynamicList.cast<List<List<double>>>();
This gives "not a sub-type error",
Therefore to convert it to List<List<double>> I have to,
List<List<double>> converted = [];
for(int i = 0; i < dynamicList.shape[0]; i++){
List<double> subList = [];
for(int j = 0; j < dynamicList.shape[1]; j++){
if(dynamicList[i][j] is double){
subList.add((dynamicList[i][j] as double));
}
}
converted.add(subList);
}
extension Util on List{
List<int> get shape {
if (isEmpty) {
return [];
}
var list = this as dynamic;
var shape = <int>[];
while (list is List) {
shape.add((list as List).length);
list = list.elementAt(0);
}
return shape;
}
}
What could be a better and more generalized way of doing this?
How to cast a List inside a List
which is a dynamic list
List<List<String>> typedList;
typedList = dynamicList.map((value)=>List.cast(value));

Dart/Flutter How to initialize a List inside a Map?

How can I initialize a list inside a map?
Map<String,Map<int,List<String>>> myMapList = Map();
I get an error :
The method '[]' was called on null.
I/flutter (16433): Receiver: null
I/flutter (16433): Tried calling: [](9)
By just adding the elements when you create the map, or later by adding them. For example:
var myMapList = <String, Map<int, List<String>>>{
'someKey': <int, List<String>>{
0: <String>['foo', 'bar'],
},
};
or
var m2 = <String, Map<int, List<String>>>{}; // empty map
m2['otherKey'] = <int, List<String>>{}; // add an empty map at the top level
m2['otherKey'][2] = <String>[]; // and an empty list to that map
m2['otherKey'][2].add('baz'); // and a value to that list
print(m2);
prints {otherKey: {2: [baz]}}
Try initializing using {}
Map<String,Map<int,List<String>>> myMapList = {}; // just add {}
it will create an empty map and works perfectly fine.
In case for list of int as value
void main() {
List<int> dividends = [99,101,176,182];
Map map = new Map<int, List<int>>();
dividends.forEach((i) {
if(i > 0) {
map[i] = <int>[];
for(int j=1; j <= i;j++) {
if(i%j == 0) {
map[i].add(j);
}
}
// print('$i, $map[$i]');
}
});
print(map);
}