Get index of list of map from map - flutter

How do you get index of list of maps from a map. I tried to use indexOf which works but by the time the position of values are mixed up then it returns -1.
UPDATE: It actually doesn't work even in right order
List<Map<String, dynamic>> list = [{'id':1, 'name':'a'}, {'id':2, 'name':'b'}];
Map<String, dynamic> item = {'name':'a','id':1}; //<- position name and id are in different places
print(list.indexOf(item)); // so it return -1
The best way would be to get index of list where item contains same id ... if you know what I mean... How to do it?

You can use indexWhere instead indexOf.
Map<String, dynamic> item = {'name':'a','id':1};
print(list.indexWhere((i) => i['id'] == item['id'])); // prints 0
Map<String, dynamic> item = {'name':'b','id':2};
print(list.indexWhere((i) => i['id'] == item['id'])); // prints 1

Related

Map getter not pulling items by index properly

I have a Map of <String, CartItem> which is a custom class, and I am trying to return specific values from that Map, but every time I do return them in the format item[I], I get a "Null check operator used on a null value." Is there a different way I should be calling this?
Details
I have a map of _items with a public getter that returns those items:
class Cart with ChangeNotifier {
Map<String, CartItem> _items = {};
Map<String, CartItem> get items {
return {..._items};
}
Followed by a function that adds new items to the Map:
void addItem(
String productId,
double price,
String title,
) {
if (_items.containsKey(productId)) {
_items.update(
productId,
(existingCartItem) => CartItem(
id: existingCartItem.id,
title: existingCartItem.title,
price: existingCartItem.price,
quantity: (existingCartItem.quantity + 1),
),
);
} else {
_items.putIfAbsent(
productId,
() => CartItem(
id: DateTime.now().toString(),
title: title,
price: price,
quantity: 1,
),
);
}
print(items.length);
print(items[0]);
print(items);
notifyListeners();
}
When I call addItem, this is the output I get from those three print statements - it appears calling as items[0] returns null, even though the length and the full items list print properly:
Performing hot restart...
Restarted application in 1,483ms.
flutter: 1
flutter: null
flutter: {p1: Instance of 'CartItem'}
Then whenever I call that Cart Provider looking for a specific item in the Map:
child: ListView.builder(
itemCount: cart.itemCount,
itemBuilder: (ctx, i) => CartItem(cart.items[i]!)),
)
I get a "Null check operator used on a null value" error. Why is this way of calling the items in the map returning null?
You seem to assume that items[0] works like an array and returns the first element. It does not. A Map has an indexer by key. It returns the item, with the given key. That is the whole point of a map, being able to look up items by key. You set your productId as a key, so to find it you would need to use items[productId].
Some thoughts: does your cart items needs to be a map? If all you want is enumerating through it, it would work if you made it a simple list instead. Then the numeric indexer would work again.
If it needs to be a map, you can use items.values to iterate through all the values. But please note that a map is not ordered. Again, if you need an ordered list, it would be better to use a list in the first place.

Set order by random in flutter dart

I want to show my category products order by random. So trying to change it but it doesn’t work.
Only date, menu order, popularity, rating these sort method working. Is there any way to set orderby random work in dart?
> #observable
Map<String, dynamic> _sort = {
'key': 'product_list_default',
'query': {
'order': 'desc',
'orderby': 'date', //want to change to random
};
this is not hard..
If your categories are in a List
e.g
List categories = [category1, category2, category3]
You can use a method like this
//first get a random index that will exist in the category list (in this case 'List categories')
Random random = new Random();
int randomNumber = random.nextInt(categories.length); //from index 0 to the last index
//now to use the random number to select a category
var randomCategory = categories[randomNumber]

Flutter Firebase Database, DataSnapshot? how to get values and keys, null safe

Using firebase_database: ^7.1.1
Before null safety i used to do like this to get the data from firebase database:
DataSnapshot dataSnapshot = await References.getReferenceYears().once();
Map<dynamic, dynamic> values = dataSnapshot.value;
values.forEach((key, value) {...}
Now when i try do like this, i get the error as bellow:
DataSnapshot? dataSnapshot = await References.getReferenceYears().once();
Map<dynamic, dynamic> values = dataSnapshot.value;
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type 'List<Object?>' is not a subtype of type 'Map<dynamic, dynamic>'
I think this means that the keys are not being returned in the dataSnapshot.value, how can i use this now to get the (key, value) as before?
If I print the snapshot.value I get like this, so looks like the keys are no longer present in the snapshot.value as before, i don't know where are the keys now:
[{name: 2016-2017}, {name: 2017-2018}, {name: 2018-2019}]
Thanks in advance.
You probably update Flutterfire cloud_firestore too, becouse as you can see from the error, in the newest versione, the data returned from the snapshot is an Object or a List<Object> and not a map.
You can solve like this:
snapshot.value as Map<String, dynamic>
EDIT:
I saw you where referring to firebase realtime database.
So the problem is not caused by flutter_fire.
The error tells you that you are trying to put a List into a Map<dynamic,dynamic>.
One solution could be:
Map<dynamic, dynamic> values = dataSnapshot.value as Map<dynamic, dynamic>;
Try this
DataSnapshot dataSnapshot = await References.getReferenceYears().once();
(dataSnapshot as Map<dynamic, dynamic>).forEach((key, value) {...}
It sounds like you have sequential, numeric keys under References.getReferenceYears(), which the SDK converts to an array. I don't think this changed in a recent SDK, as Firebase always tries to coerce such keys into an array.
If you don't want the values to be stored into an array, the easiest way to prevent that is to prefix the keys with a short non-numeric value, like:
"key_0": "value 0",
"key_1": "value 1",
"key_2": "value 2",
...
Use version 8.x.x for now as output type is dynamic instead of Object? in version 9.x.x
Map<dynamic, dynamic> mapData;
snapshot.values.forEach((key, value) {
mapData[key][value];
})

Filter and get a new Map from ' Map<String,ProductItem>myMap' in dart

I have a Map in dart as
Map<String, List<ProductItem>> _productItemsMap;
I want to filter and get a new Map<String, List<ProductItem>> _newMap
which has the Product Item's id the same as my condition.
How can I do that in dart?
Thanks for you help.
Here are a few ways:
Use collection-for to create a new Map and use collection-if to filter:
var _newMap = {
for (var entry in _productItemsMap.entries)
if (satisfiesCondition(entry.key, entry.value))
entry.key: entry.value,
};
Filter with Iterable.where and create a new Map with Map.fromEntries:
var _newMap = Map.fromEntries(_productItemsMap.entries
.where((entry) => satisfiesCondition(entry.key, entry.value)));
Copy the Map first with Map.of and then remove the items you don't want:
var _newMap = Map.of(_productItemsMap)
..removeWhere((key, value) => !satisifiesCondition(key, value));

Handle null value in Dart / Flutter

I have this User class and then a Firestore Document, that may or may not contain a photoURL or some other values. The problem is, that when I try to create an user I get this exception because some of the values are Null.
I've tried to handle it like this:
var photoURL = snapshot.data['photoURL'] ??= '';
but it seems it doesn't work.
Can anyone explain best practices handling Null values in Dart/Flutter respectively?
EDIT: I'm checking if snapshot.exists before and if I create the user omitting the values I know are Null, it creates it properly.
EDIT 2: I've found the problem appears when I try to handle empty List like this:
var favorites = snapshot.data['favorites'] ?? [''];
It seems I was initialized the value the wrong way when I converted it to Json.
I handle the empty Array like this
Map<String, dynamic> toJson() => {
'favorites' : favorites ?? '',
}
when it should be:
Map<String, dynamic> toJson() => {
'favorites' : favorites ?? [''],
}
So it was throwing when I tried to assign an empty Array to String.