How can i searching from Map<String, List<dynamic>> Flutter - json

i'm try to make Search Bar and Searching from Map<String, List>
but i got error like this --> "A value of type 'Iterable<MapEntry<String, List>>'
can't be assigned to a variable of type 'Map<String, List>"
//here the function that i try.
Map<String, List> datasource_map = {};
Map<String, List> result = {};
void updateList(String enteredKeyword) {
setState(() {
result = datasource_map.entries.map((e) {
return MapEntry(
e.key,
e.value
.where(
(element) => element.foodName!.toLowerCase().contains(
enteredKeyword.toLowerCase(),
),
)
.toList());
});
print("### $result");
});
}
this is my Model of foodCard
what should i try ? i am new at flutter

Looks like your datasource_map.entries is a List - calling a map() on it will produce an Iterator - not a Map object.
You should use Map.fromEntries constructor:
result = Map.fromEntries(datasource_map.entries.map((e) {
return MapEntry(
e.key,
e.value
.where(
(element) => element.foodName!.toLowerCase().contains(
enteredKeyword.toLowerCase(),
),
)
.toList());
}));

Thank you everyone! I solved it.
This works:
Map<String, List<dynamic>> result = {};
void updateList(String enteredKeyword) {
Map<String, List<dynamic>> mapResult = {};
datasource_map.forEach((key, value) {
List foodByFilter = value.where((element) {
return element.foodName
.toLowerCase()
.contains(_textEditingController.text.toLowerCase().toString());
}).toList();
if (foodByFilter.isNotEmpty) mapResult[key] = foodByFilter;
});
setState(() {
result = mapResult;
});
}

Related

The argument type 'Object?' can't be assigned to the parameter type 'Map<dynamic, dynamic>

I want to get a category section from Firebase Firestore so I used this class
class CategoryModel {
late String name, image;
CategoryModel({
required this.name,
required this.image,
});
CategoryModel.fromJson(Map<dynamic, dynamic> map) {
if (map == null) {
return;
}
name = map['name'];
image = map['image'];
}
toJson() {
return {
'name': name,
'image': image,
};
}
}
and then I created this with gets
class HomeViewModel extends GetxController {
ValueNotifier<bool> get loading => _loading;
ValueNotifier<bool> _loading = ValueNotifier(false);
List<CategoryModel> get categoryModel => _categoryModel;
List<CategoryModel> _categoryModel = [];
HomeViewModel() {
getCategory();
}
getCategory() async {
_loading.value = true;
await HomeService().getCategory().then((value) {
for (int i = 0; i < value.length; i++) {
_categoryModel.add(
CategoryModel.fromJson(
value[i].data(),
),
);
_loading.value = false;
}
update();
});
}
}
but when I try to get categories from Firestore with the function getCategory() this error comes
Error in vs code
Error in Problems scetion
Try it this way and tell me if it's fixed.
CategoryModel.fromJson(
value[i].data() as Map<String,dynamic>,
),
You can read more about Cloud Firestore 2.0 here.
The basic idea is that wherever you are trying to read the data from a DocumentSnapshot, you need to cast the Object? to Map<String, dynamic>.
You can do this in a few ways.
Cast the Object? to Map<String, dynamic> in your toJson method
CategoryModel.fromJson(
value[i].data() as Map<String,dynamic>,
),
Specify the type in your constructors
DocumentReference<Map<String, dynamic>> documentReference;
Specify the type in your StreamBuilder
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: model.testSnap,
builder: (context, snapshot) {
return Container();
},
)

Flutter compute method and filter results in json

I'm a really fresh new dev in flutter, I'm trying to filter results in a json response based on the title.
And i would like to use the compute method. This method only allow 2 arguments, so it's why i think i need to use a map to get the response.body and the query for filtering.
This is my HttpService :
class HttpService {
static List<Post> _parsePosts(Map map) {
print(map);
return map["body"].map((json) => Post.fromJson(json)).where((post) {
final titleLower = post.title.toLowerCase();
final queryLower = map["query"].toLowerCase();
return titleLower.contains(queryLower);
}).toList();
}
static Future<List<Post>> fetchPosts(String query) async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
final response = await retry(
() => http.get(uri).timeout(Duration(seconds: 10)),
retryIf: (e) => e is SocketException || e is TimeoutException,
);
Map posts = new Map();
posts["body"] = json.decode(response.body);
posts["query"] = query;
if (response.statusCode == 200) {
return compute(_parsePosts, posts);
} else {
throw Exception("Failed to load posts ${response.statusCode}");
}
}
}
The print(map); contains the map with values -> https://prnt.sc/131ldey
But the problem is reported on : return map["body"].map((json) => Post.fromJson(json)).where((post) {
with : _TypeError (type '(dynamic) => dynamic' is not a subtype of type '(dynamic) => bool' of 'test')
I really don't understand what is the reason of this error..
Your titleLower is not casted into a String type! So the contains method returns a dynamic value since it does not appear as the contains method of the String type for the VM !
final String myValue = ...;
return myValue.contains(‘a’);

flutter foreach loop on json response from API

I have converted my JSON response in the below model:
VehicleList vehicleListFromJson(String str) =>
VehicleList.fromJson(json.decode(str));
String vehicleListToJson(VehicleList data) => json.encode(data.toJson());
class VehicleList {
VehicleList({
this.vehicles,
});
List<Vehicle> vehicles;
factory VehicleList.fromJson(Map<String, dynamic> json) => VehicleList(
vehicles: List<Vehicle>.from(
json["vehicles"].map((x) => Vehicle.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"vehicles": List<dynamic>.from(vehicles.map((x) => x.toJson())),
};
}
class Vehicle {
Vehicle({
this.vehid,
this.vehname,
this.vehdescrip,
this.vehbodyopen,
this.vehbodyopenimg,
this.vehbodyclose,
this.vehbodycloseimg,
});
String vehid;
String vehname;
String vehdescrip;
String vehbodyopen;
String vehbodyopenimg;
String vehbodyclose;
String vehbodycloseimg;
factory Vehicle.fromJson(Map<String, dynamic> json) => Vehicle(
vehid: json["vehid"],
vehname: json["vehname"],
vehdescrip: json["vehdescrip"],
vehbodyopen: json["vehbodyopen"],
vehbodyopenimg: json["vehbodyopenimg"],
vehbodyclose: json["vehbodyclose"],
vehbodycloseimg: json["vehbodycloseimg"],
);
Map<String, dynamic> toJson() => {
"vehid": vehid,
"vehname": vehname,
"vehdescrip": vehdescrip,
"vehbodyopen": vehbodyopen,
"vehbodyopenimg": vehbodyopenimg,
"vehbodyclose": vehbodyclose,
"vehbodycloseimg": vehbodycloseimg,
};
}
I make the API call like this:
Future<VehicleList> getVehicles() async {
var client = http.Client();
var vehicleModel = null;
try {
var response = await client.get(Uri.parse(Strings.getVehiclesUrl));
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
vehicleModel = VehicleList.fromJson(jsonMap);
}
} catch (Exception) {
return vehicleModel;
}
return vehicleModel;
}
Now I need to implement a for each loop on this to check if the value for key "vehbodyopen" is "Y" or "N" and create seperate arrays or objects for them and then display them in a ListViewBuilder widget.
Im new to flutter. Im from javascript background. I solved the problem in javascript by executing for each loop in the json response and stored them in two different arrays. Im looking for the same solution in flutter and dart if possible.
for (int i = 0; i < vehicleModel.length; i++) {
if(vehicleModel[i].vehbodyopen == "Y"){
//do stuff
}else{
//do another stuff
}
}
you might try this
I found a possible solution I had to loop over the vehicles List inside the vehicleModel.
List vehList = vehicleModel.vehicles;
List openVehList = [];
List closedVehList = [];
for (var veh in vehList) {
print('executing foreach');
if (veh.vehbodyopen == "Y") {
openVehList.add(veh);
} else {
closedVehList.add(veh);
}
}

Api Call With Nested Map Flutter

I am trying to make a POST call to my server that requires my data to be shaped like this:
{
"dispensary": 1,
"order_detail": [
{"product_size": 1,
"quantity": 1}
]
}
But when I make my api call, I get a 500 error on my back end saying the data looks like this:
{'{"dispensary":1,"order_detail":{"product_size":1,"quantity":1}}': ['']}
I am making the call like this:
Future getdata(dispensary, order) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var token = prefs.getString('token');
var url = '$server/api/customer/order/getdata/?access_token=$token';
Map<String, dynamic> orderRating = {
'dispensary': dispensary,
'order_detail': order
};
await http.post(url, body: orderRating, headers: {
"Content-Type": "application/x-www-form-urlencoded"
}).then((http.Response response) {
switch (response.statusCode) {
case (200):
var responseData = json.decode(response.body);
Rate rateData =
Rate.fromJson((responseData[1]['rate_response']['rates']));
print('uploaded successfully');
print(rateData.carrierId);
break;
case (400):
print('Bad Data');
break;
case (500):
print('Failed Upload');
isUploaded = false;
break;
default:
print('Unable to get rates');
}
});
print('uploaded successfully');
}
With order_detail being a map itself of {"product_size": 1,
"quantity": 1}.
I cannot complete the call to my server. Could you tell me what I'm doing wrong
I don't get exactly what are you doing, because it's not the whole future function in it ... but I can make a guess you're trying to make a post request, where the body have some dynamic data.
What are you doing right now as far as I can see is that you're putting a map inside a map which is not what you want.
My suggestion is something like this:
Future<http.Response> postSomething(int dispensary, List<Map<String,dynamic>> order) async {
final String url = 'yoururl';
final Map<String, dynamic> body = {
'dispensary': dispensary,
'order_detail': order
};
final request = await http.post(url: url, body: convert.jsonEncode(body));
if(request.statusCode == 200) {
return something
} else {
throw Exception('Failed to send the request!!!')
}
}
Hope that my answer will help you and give a clearer idea. :)
Add the toJson methods to your objects. call toJson when generating your requests body
body: orderRating.toJson
should return the json structure as seen in this snippet
{
"dispensary": 1,
"order_detail": [
{"product_size": 1,
"quantity": 1}
]
}
class OrderRating{
int dispensary;
List<OrderDetail> orderDetail;
OrderRating({this.dispensary, this.orderDetail});
OrderRating.fromJson(Map<String, dynamic> json) {
dispensary = json['dispensary'];
if (json['order_detail'] != null) {
orderDetail = new List<OrderDetail>();
json['order_detail'].forEach((v) {
orderDetail.add(new OrderDetail.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['dispensary'] = this.dispensary;
if (this.orderDetail != null) {
data['order_detail'] = this.orderDetail.map((v) => v.toJson()).toList();
}
return data;
}
}
class OrderDetail {
int productSize;
int quantity;
OrderDetail({this.productSize, this.quantity});
OrderDetail.fromJson(Map<String, dynamic> json) {
productSize = json['product_size'];
quantity = json['quantity'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['product_size'] = this.productSize;
data['quantity'] = this.quantity;
return data;
}
}
The above code was generated using a tool found Here

Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<Model>'

I am trying to parse Json data that I get from an online API but get the error mentioned in the title. I looked at similar questions but could not find a solution.
Here is the relevant code:
class Model {
final double a;
final double b;
final String s;
Model._({this.a, this.b, this.s});
factory Model.fromJson(Map<String, dynamic> json) {
return new Model._(
a: json['a'],
b: json['b'],
s: json['s'],
);
}
}
void fetchPairValue() async {
final response = await http.get('https://api.1forge.com/quotes?pairs=USD/TRY,EUR/USD,EUR/TRY,CAD/TRY,GBP/TRY,AUD/TRY,JPY/TRY,CHF/TRY,AED/TRY,USD/QAR,USD/BGN,DKK/TRY,USD/SAR,USD/CNY,USD/RUB,NOK/TRY,SEK/TRY'
'&api_key=KatWbQa9sDFmYQ25LmtAMlGau5xKSWIe');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
List<Model> list = json.decode(response.body).map((data) => Model.fromJson(data))
.toList();
setState(() {
currencyPair[0][1] = round_to_4(list[0].b).toString();
currencyPair[0][2] = round_to_4(list[0].a).toString();
for (int i = 1; i < currencyPair.length; i++) {
if(list[i].s.startsWith('USD'))
{
currencyPair[i][1] = round_to_4(list[i].b/list[1].b).toString();
currencyPair[i][2] = round_to_4(list[i].a/list[1].a).toString();
}
else {
currencyPair[i][1] = round_to_4(list[i].b).toString();
currencyPair[i][2] = round_to_4(list[i].a).toString();
}
}
});
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
Sample Json Data:
[{"p":1.21856,"a":1.22201,"b":1.2151,"s":"EUR/USD","t":1608934265255},{"p":7.5575,"a":7.5625,"b":7.5525,"s":"USD/TRY","t":1608908143931},{"p":9.26299,"a":9.27256,"b":9.25342,"s":"EUR/TRY","t":1608879625018},{"p":6.037513,"a":6.039437,"b":6.035589,"s":"CAD/TRY","t":1608933871214},{"p":10.297348,"a":10.316695,"b":10.278,"s":"GBP/TRY","t":1608879629130},{"p":5.7738,"a":5.7885,"b":5.7591,"s":"AUD/TRY","t":1608879564069},{"p":0.07303697,"a":0.07308529,"b":0.07298864,"s":"JPY/TRY","t":1608908143937},{"p":8.529457,"a":8.538269,"b":8.520645,"s":"CHF/TRY","t":1608879624835},{"p":2.057672,"a":2.059033,"b":2.056311,"s":"AED/TRY","t":1608908143934},{"p":3.6413,"a":3.642,"b":3.6405,"s":"USD/QAR","t":1608847204796},{"p":1.6069188,"a":1.61497,"b":1.5988675,"s":"USD/BGN","t":1608861813327},{"p":1.2452666,"a":1.2465531,"b":1.24398,"s":"DKK/TRY","t":1608879625024},{"p":3.752353,"a":3.755106,"b":3.7496,"s":"USD/SAR","t":1608879629251},{"p":6.5418,"a":6.5428,"b":6.5408,"s":"USD/CNY","t":1608909993197},{"p":74.06,"a":74.095,"b":74.025,"s":"USD/RUB","t":1608930021562},{"p":0.87736,"a":0.878167,"b":0.876553,"s":"NOK/TRY","t":1608847205092},{"p":0.917155,"a":0.918032,"b":0.916278,"s":"SEK/TRY","t":1608847203927}]
How to fix? Thanks.
You need to add the generic type to the map function:
List<Model> list = json
.decode(response)
.map<Model>((data) => Model.fromJson(data))
.toList();