Flutter convert JSON string to multi-level list - json

I want to convert a string to multi-level list, but I cannot find a efficient way to do.
From String:
[[1,2,3],[1,2]]
To List:
List< List < int>>

Try this as a funtion
List<List<int>> convert(String val){
List<List<int>> list = [];
jsonDecode(val).forEach((mainList) {
List<int> subList = [];
mainList.forEach((sList) {
subList.add(sList);
});
list.add(subList);
});
return list;
}
Also import dart:convert;

String str = '[[1,2,3],[1,2]]';
List<List<int>> list=[];
for(String s in str.split('],[')){
List<int> l = [];
String formattedString = s.replaceAll('[','').replaceAll(']','');
for(String innerS in formattedString.split(',')){
l.add(int.parse(innerS));
print(l);
}
list.add(l);
}
Output: [[1, 2, 3], [1, 2]]

Shorter version:
import 'dart:convert';
void main() {
var jsonMap = "[[1,2,3],[1,2]]";
List<List<int>> items = (jsonDecode(jsonMap) as List).map((lst) =>
(lst as List).map((i) => (i as int)).toList()).toList();
print(items);
}

Related

How do I join Keys and Values. Flutter/Dart

This is my code right now :
List<Map<String, dynamic>> incidentList = [
for (final json in listNode.map((x) => x.toJson()))
{
'Code': json['field'][0]['field_value'],
'Description': json['field'][1]['field_value'],
'Organisation Unit': json['field'][2]['field_value'],
'Date Reported': json['field'][3]['field_value'],
'Status': json['field'][4]['field_value'],
'RunHyperlink' : json['run_hyperlink']
}
];
final List<String> values = [];
for(final item in incidentList){
values.add(item.keys.map((e) => e.toString()).join("\n"));
values.add(item.values.map((e) => e.toString()).join("\n"));
}
await WriteCache.setListString(key: 'cache4', value: values);
How do I combine the keys and value so that my list is in the format of "key : value" instead of just value
You can run a nested loop
for(final item in incidentList){
String groupedElement = "";
for(var innerItem in item.entries)
{
groupedElement += "${innerItem.key}:${innerItem.value},";
}
value.add(groupedElement);
}
You can Not shure what format you want, but is sound like JSON. So if you want JSON
You can just replace:
await WriteCache.setListString(key: 'cache4', value: json.encode(incidentList));
Don't forget to import dart:convert:
import 'dart:convert';
And remove:
final List<String> values = [];
for(final item in incidentList){
values.add(item.keys.map((e) => e.toString()).join("\n"));
values.add(item.values.map((e) => e.toString()).join("\n"));
}
ATTENTION, this will return a String, not a list of String
For retrieveing a Map<String, dynamic> from your save data, just do:
final jsonData = json.decode(savedJsonStr);

Flutter: Group by Array List of Json String by Id

String jsonString = [{"color":"#000000","quantity":"100","price":"999","attribute":{"id":1,"name":"SIZE"}},{"color":"#cd7d96","quantity":"40","price":"555","attribute":{"id":2,"name":"FABRIC"}},{"color":"#66cccc","quantity":"500","price":"1000","attribute":{"id":1,"name":"SIZE"}}]
How can I group by and archive results as below
[{"attribute_id":1, "values":["#000000","#66cccc"]},{"attribute_id":2, "values":["#cd7d96"]}]
import 'dart:convert';
const raw =
'''
[{"color":"#000000","quantity":"100","price":"999","attribute":{"id":1,"name":"Iphone 12"}},{"color":"#cd7d96","quantity":"40","price":"555","attribute":{"id":2,"name":"SAMSUNG"}},{"color":"#66cccc","quantity":"500","price":"1000","attribute":{"id":1,"name":"OPPO"}}]
''';
typedef JMap = Map<String, dynamic>;
typedef LJMap = List<JMap>;
void groupById() {
final data = (jsonDecode(raw) as List).cast<JMap>();
var result = <JMap>[];
data.map<int>((m) => m['attribute']['id']).toSet().forEach((e) {
result.add({
'attribute_id': e,
'values': data.where((m) => m['attribute']['id'] == e).map((m) => m['color']).toList(),
});
});
print(result);
}
void main(List<String> args) {
groupById();
}
Output:
[{attribute_id: 1, values: [#000000, #66cccc]}, {attribute_id: 2, values: [#cd7d96]}]

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);
}
}

Flutter Dart deserialize a json with dynamic key but structured values into Map<String, ModelClass>

Is it possible to deserialize a json with dynamic key but structured values into Map in flutter dart.
I am having a json like
{
"data" : {
"apple":{"qty":5, "price":100},
"orange":{"qty":2, "price":40},
}
}
And I want this to deserialize in flutter/dart to a model class below
class Data {
Map<String, Item> itemMap;
factory Data.fromJson(Map<String,dynamic> json) {
itemMap : json["data"]; //How to parse.
}
}
class Item {
int qty;
int price;
}
I have read through a medium blog and even this also not covering the Map part.
You need to do something like this:
//...
Future<List<ItemModel>> fetchFood() async {
List<ItemModel> foodItemsList = [];
// Get json response and parse it as a Map<String, dynamic>
final response = {
"data" : {
"apple":{"qty":5, "price":100},
"orange":{"qty":2, "price":40},
}
};
// with your real get request use this:
// final parsedJson = json.decode(response.body)['data'];
// Parsed Json have what's inside data, in case of real request look for the line above this.
final parsedJson = response['data'];
// Iterate over all fruits and create Item object from each,
// then push to a list of Item's objects to return it.
parsedJson.forEach((k,v) => foodItemsList.add(ItemModel.fromJson(v)));
return foodItemsList;
}
// Item model
class ItemModel {
int qty;
int price;
ItemModel.fromJson(Map<String,dynamic> parsedJson)
: qty = parsedJson['qty'],
price = parsedJson['price'];
}
// Then call it
main() async {
List<ItemModel> foodItemsList = await fetchFood();
//..
}
If you need the fruit name as part of the object:
//...
Future<List<ItemModel>> fetchFood() async {
List<ItemModel> foodItemsList = [];
// Get json response and parse it as a Map<String, dynamic>
final response = {
"data" : {
"apple":{"qty":5, "price":100},
"orange":{"qty":2, "price":40},
}
};
// with your real get request use this:
// final parsedJson = json.decode(response.body)['data'];
// Parsed Json have what's inside data, in case of real request look for the line above this.
final parsedJson = response['data'];
// Iterate over all fruits and create Item object from each,
// then push to a list of Item's objects to return it.
parsedJson.forEach((fruitName, fruitDetails)
=> foodItemsList.add(
ItemModel.fromJson(fruitName, fruitDetails)
)
);
return foodItemsList;
}
// Item model
class ItemModel {
String name;
int qty;
int price;
ItemModel.fromJson(String fruitName, Map<String,dynamic> parsedJson)
: name = fruitName,
qty = parsedJson['qty'],
price = parsedJson['price'];
}
// Then call it
main() async {
List<ItemModel> foodItemsList = await fetchFood();
print(foodItemsList[1].name); //orange
//..
}
I have a similar JSON with a few changes:
{
"sub_item": {
"491": ["92837|1.3|Pistachio|right", "92838|2.5|Hazelnut|left"],
"427": ["92839|7.05|Almonds|", "92840|5.12|Walnuts|"],
"396": ["92841|15|Saffron|"],
"275": ["92842|45|Caviar|"]
}
}
The keys of sub_item map (491, 427, 396, 275, and...) are dynamic(as a label not as a type) and will change per order. For example, it will be 376, 325, 493... in another order.
I want to shows both keys and values on my Flutter app and do not know how to fetch these data and show them separately. Something like this:
491:
£1.30 Pistachio
£2.50 Hazelnut
427:
£7.05 Almonds
£5.12 Walnuts
396:
£15.00 Saffron
275:
£45.00 Caviar
I used this code and it worked for me somehow but it shows only the first item of the lists. for example, it shows only Pistachio for 491 not Hazelnut and the same it shows only Almonds for 427 not Walnuts:
Future<List<ItemModel>> fetchFood() async {
List<ItemModel> foodItemsList = [];
final response = {
"sub_item": {
"491": ["92837|1.3|Pistachio|right", "92838|2.5|Hazelnut|left"],
"427": ["92839|7.05|Almonds|", "92840|5.12|Walnuts|"],
"396": ["92841|15|Saffron|"],
"275": ["92842|45|Caviar|"]
}
};
final parsedJson = response['sub_item'];
parsedJson.forEach((fruitName, fruitDetails) =>
foodItemsList.add(ItemModel.fromJson(fruitName, fruitDetails)));
return foodItemsList;
}
// Item model
class ItemModel {
String id;
String details;
ItemModel.fromJson(String subItemID, List<dynamic> subItemDetails)
: id = subItemID,
details = subItemDetails[0];
}
// Then call it
mainTest() async {
List<ItemModel> foodItemsList = await fetchFood();
for (var i = 0, j = 0;
i < foodItemsList.length;
j < foodItemsList[i].details.length, i++, j++) {
print(foodItemsList[i].id);
print(foodItemsList[j].details.split('|')[2]);
}
}
The console result:
flutter: 491
flutter: Pistachio
flutter: 427
flutter: Almonds
flutter: 396
flutter: Saffron
flutter: 275
flutter: Caviar
I found a way to achieve it. We can convert the Map from one type to another.
class Data {
Map<String, Item> itemMap;
factory Data.fromJson(Map<String,dynamic> json) {
itemMap : getMapDataFrom(json["data"]); //How to parse.
}
static Map<String, Item> getFruitItemMap(Map<String, dynamic> map) {
final Map<String, Item> fruitItemMap = HashMap();
map.forEach((name, value) {
bitItemLites[name] = Item.fromJson(value, name);
});
return bitItemLites;
}
}
class Item {
int qty;
int price;
factory Item.fromJson(Map<String,dynamic> json) {
return Item(json['qty'], json['price']);
}
}

Serialize List<int> to json using JsonConvert class

I am using Newtonsoft.dll and this is the scenario,
List<int> listNumbers = new List<int>() { 1, 2, 3, 4, 5};
var result = JsonConvert.SerializeObject(listNumbers);
the result is ,
[1,2,3,4,5]
But I want the following type of result,
[{"cardvalue":1},{"cardvalue":2},{"cardvalue":3},{"cardvalue":4},{"cardvalue":5}]
How can I do this ?
Try-
var result = listNumbers.Select(a => new
{
cardvalue = a
});
var jsonResult = JsonConvert.SerializeObject(result);
or serialize result directly -
var result = JsonConvert.SerializeObject(listNumbers.Select(a => new
{
cardvalue = a
}));