How to convert or equalize Query<Map<String, dynamic>> to List - list

I have BrandList in my Firebase like this;
How can I convert or equalize this Firebase List to List.
I tried this;
var brandsRef = _firestore.collection("vehicles1").where("Brands");
List brandsList = brandsRef;
But I got this error "A value of type 'Query<Map<String, dynamic>>' can't be assigned to a variable of type 'List'."

You need to use the document Id to get the query and then you can get the data which returns a Map.
From that Map, you can supply the key to retrieve the value. In this case, the key is "Brands".
var brandsQuery = await _firestore.collection("vehicles1").doc(document Id).get();
List brandList = brandsQuery.data()["Brands"];

First I would suggest to create a model of your class Brand in addition to the jsonSerialization classics:
class Brands {
Brands({this.brandName});
List<String> brandName;
Map<String, dynamic> toMap() {
return {
'Brands': brandName,
};
}
factory Brands.fromMap(Map<String, dynamic> map) {
return Brands(
brandName: List<String>.from(map['Brands']),
);
}
String toJson() => json.encode(toMap());
factory Brands.fromJson(String source) => Brands.fromMap(json.decode(source));
}
Then you need to add a few steps to the way you retreive elements:
var response = _firestore.collection("vehicles1").where("Brands").get();
final results =
List<Map<String, dynamic>>.from(response.docs.map((e) => e.data()));
Brands brands =
results.map((e) => Brands.fromMap(e)).toList();

Related

Flutter : how save list of dynamic to shared preference

I am trying to save a list of data to shared preference and read these articles but don't works with me :
Flutter save List with shared preferences
Shared Preferences in Flutter cannot save and read List
I have this list :
var list =[
{
"id" : 1,
"name" : "ali"
},
{
"id" : 2,
"name" : "jhon"
}
];
I tried this :
setList() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final SharedPreferences prefs = await _prefs;
prefs.setStringList('list', list);
}
I get this error : The argument type 'List<Map<String, Object>>' can't be assigned to the parameter type 'List<String>'
The error occurs because your list is of type Map<String, Object> and not a String. To fix this you can use jsonEncode method which converts it into a String
Future<void> setList() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final List<String> jsonList = list.map((item) => jsonEncode(item)).toList();
prefs.setStringList('list', jsonList);
}
If you now want to retrieve this list you have to use jsonDecode to convert it back to a Map<String, Object>.
List<Map<String, Object>> getList() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final List<String> jsonList = prefs.getStringList('list')
final List<Map<String, Object> list = jsonList.map((item) => jsonDecode(item)).toList();
return list;
}

How to add elements dynamically in a 2d list from another list in Flutter?

I have a list of model class objects. Such as -
List<ModelChannel> allChannels = [];
I have added elements in this list from json. Model Class variables are-
final String channelid;
final String channelname;
final String channeltype;
final String categoryname;
final String channelimage;
final String channelurl;
Here categorytype contains country information. I want to divide the list country wise dynamically. I have intended to use 2d list where each row will contain all the channels of a specific country. Is this the right approach? If yes how to implement this and if not what will be the right one?
If I understand correctly, you are looking for groupBy function from collection package.
Add this package to your pubspec.yaml:
dependencies:
collection: any
And use groupBy:
import 'package:collection/collection.dart';
...
final groupByCountry = groupBy(allChannels, (ModelChannel e) => e.categoryname);
List<List<ModelChannel>> countryList = [];
List<String> channelType = [];
allChannels.forEach((element) {
if (channelType.isEmpty) {
channelType.add(element.channeltype);
} else {
if (channelType.contains(element.channeltype)) {
} else {
channelType.add(element.channeltype);
}
}
});
channelType.forEach((countryCode) {
List<ModelChannel> t = [];
allChannels.forEach((element) {
if (element.channeltype == countryCode) {
t.add(element);
}
});
countryList.add(t);
});

How to convert list getting from future method to Map<String, dynamic>

I want to convert the list coming from getPosts method (getting result from the web json and stored in the posts list) to List
Post Class
class Post {
final int userId;
final String id;
final String title;
final String body;
Post(this.userId, this.id, this.title, this.body);
}
Future<List<Post>> getPosts() async {
var data = await http
.get("https://jsonplaceholder.typicode.com/posts");
var jasonData = json.decode(data.body);
List<Post> posts = [];
for (var i in jasonData) {
Post post = Post(i["userId"], i["id"], i["title"], i["body"]);
posts.add(post);
}
return posts;
}
I tried to put the result directly to this method
static List<Map> convertToMap({List myList }) {
List<Map> steps = [];
myList.forEach((var value) {
Map step = value.toMap();
steps.add(step);
});
return steps;
}
but it's not working, I see this error
The argument type 'List<Map<dynamic, dynamic>>' can't be assigned to the parameter type 'Map<String, dynamic>'.
Change List<Map> by List<Map<String, dynamic>>
static List<Map<String, dynamic>> convertToMap({List myList }) {
List<Map<String, dynamic>> steps = [];
myList.forEach((var value) {
Map step = value.toMap();
steps.add(step);
});
return steps;
}

Search and find the string in List of DTO class in flutter?

I have this DTO class and in response of API i get the list of this :
class ProjectCode {
String id;
String projectCode;
String projectTitle;
ProjectCode({this.id, this.projectCode, this.projectTitle});
ProjectCode.fromJson(Map<String, dynamic> json) {
id = json['Id'];
projectCode = json['ProjectCode'];
projectTitle = json['ProjectTitle'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Id'] = this.id;
data['ProjectCode'] = this.projectCode;
data['ProjectTitle'] = this.projectTitle;
return data;
}
}
now how can i search in list and find the ProjectTitle that i need to find it and that method return the id in DTO ?
This is simple, you can use this method to find the String that you need to find. make method like this for everything do you need to search like this :
String find(List<ProjectCode> projectCodeList, String projectTitle) {
return projectCodeList
.firstWhere(
(projectCode) => projectCode.projectTitle.contains(projectTitle))
.id;
}

How can I distinct a complex object list in DART

I have one list of complex object. How can I distinct the list using their IDs?
I cant use toSet and similars, because the hashcode from the objects all are diferent.
1) Vanilla Dart
Loop through the list, adding IDs to a set as you go. Whenever you add an ID to the set that didn't already exist, add that element to a new list of distinct values.
void main() {
var list = [
Data('a'),
Data('a'),
Data('b'),
Data('c'),
];
var idSet = <String>{};
var distinct = <Data>[];
for (var d in list) {
if (idSet.add(d.id)) {
distinct.add(d);
}
}
}
class Data {
Data(this.id);
final String id;
}
2) Packages
Several packages exist that expand on default the Iterable utility methods, such as flinq or darq. They add a distinct method you can call to easily get a list of unique members of a list based on some property of the members.
import 'package:darq/darq.dart';
void main() {
var list = [
Data('a'),
Data('a'),
Data('b'),
Data('c'),
];
var distinct = list.distinct((d) => d.id).toList();
}
(Disclaimer, I am the maintainer of darq.)
Try to use this extension:
extension IterableExtension<T> on Iterable<T> {
Iterable<T> distinctBy(Object getCompareValue(T e)) {
var result = <T>[];
this.forEach((element) {
if (!result.any((x) => getCompareValue(x) == getCompareValue(element)))
result.add(element);
});
return result;
}
}
Using:
var distinctList = someList.distinctBy((x) => x.oid);
Or you can use a hash there.