I have a Model of Task =>
class Task {
Task({this.isDone,this.name,this.time,this.priorityValue});
final String name;
bool isDone;
final DateTime time;
int priorityValue;
factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
name: jsonData['name'],
isDone: false,
time: jsonData['time'],
priorityValue: jsonData['priorityValue'],
);
}
toJSONEncodable() {
Map<String, dynamic> m = new Map();
m['name'] = name;
m['isDone'] = isDone;
m['time'] = time;
m['priorityValue'] = priorityValue;
return m;
}
static Map<String, dynamic> toMap(Task task) => {
'name': task.name,
'isDone': task.isDone,
'time': task.time,
'priorityValue': task.priorityValue,
};
}
and When using the localStorage package to save some list of objects I got this error =>
(Flutter) Unhandled Exception: Converting object to an encodable object failed: Instance of 'DateTime'
_saveToStorage() {
storage.setItem('tasks', list.toJSONEncodable());
print("Saved");
}
i tried to use .toString() but then i get this error => type 'String' is not a subtype of type 'int' of 'index'
any Idea to save Datetime on LocalStorage package?
Update:
factory Task.fromJson(Map<String, dynamic> jsonData) {
return Task(
name: jsonData['name'],
isDone: false,
time: jsonData["time"] == null ? null : DateTime.parse(jsonData["time"]),
priorityValue: jsonData['priorityValue'],
);
}
toJSONEncodable() {
Map<String, dynamic> m = new Map();
m['name'] = name;
m['isDone'] = isDone;
m['time'] = time == null ? null : time.toIso8601String();
m['priorityValue'] = priorityValue;
return m;
}
static Map<String, dynamic> toMap(Task task) => {
'name': task.name,
'isDone': task.isDone,
'time': task.time,
'priorityValue': task.priorityValue,
};
var items = storage.getItem('tasks');
if (items != null) {
list.items = List<Task>.from(
(items as List).map(
(item) => Task(
name: item['name'],
isDone: item['isDone'],
time: DateTime.parse(item['time']),
priorityValue: items['priorityValue'],
),
),
);
}
after the update i got this error "type 'String' is not a subtype of type 'int' of 'index'"
Update2:
var items = storage.getItem('tasks');
if (items != null) {
final decodedJson = jsonDecode(items);
list.items = (decodedJson as List)
.map((e) => Task.fromJson(e))
.toList();
final task = list.items.first;
print("${task.name}");
// list.items = List<Task>.from(
// (items as List).map(
// (item) => Task(
// name: item['name'],
// isDone: item['isDone'],
// time: DateTime.parse(item['time']),
// priorityValue: items['priorityValue'],
// ),
// ),
// );
}
fter the second update i got "type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'"
Fixed
i changed the DaeTme toa String in the model and convert the time to a string when got it by
"${selectedDate.toLocal()}".split(' ')[0]
use toJson
"changeDate": changeDate == null ? null : changeDate.toIso8601String(),
and fromJson
changeDate: json["changeDate"] == null ? null : DateTime.parse(json["changeDate"]),
I'd highly recommend you to use Retrofit and json_serializable for describing your API
It could look like so:
import 'package:json_annotation/json_annotation.dart';
part 'task.g.dart';
#JsonSerializable(nullable: false, explicitToJson: true)
class Task {
final String name;
bool isDone;
final DateTime time;
int priorityValue;
Task({this.isDone, this.name, this.time, this.priorityValue});
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
Map<String, dynamic> toJson() => _$TaskToJson(this);
}
after that you need to run build_runner:
flutter pub run build_runner build
and it will generate you both toJson and fromJson methods without any pain:
Task _$TaskFromJson(Map<String, dynamic> json) {
return Task(
isDone: json['isDone'] as bool,
name: json['name'] as String,
time: DateTime.parse(json['time'] as String),
priorityValue: json['priorityValue'] as int,
);
}
Map<String, dynamic> _$TaskToJson(Task instance) => <String, dynamic>{
'name': instance.name,
'isDone': instance.isDone,
'time': instance.time.toIso8601String(),
'priorityValue': instance.priorityValue,
};
You can check out the test:
void main() {
test('Task should be parsed from json', () {
const json = '''
[
{
"name": "testing",
"isDone": false,
"time": "2021-01-12T13:57:10.705476",
"priorityValue": 0
}
]
''';
final List decodedJson = jsonDecode(json);
final List<Task> list = decodedJson.map((e) => Task.fromJson(e)).toList();
final Task task = list.first;
expect(task.name, 'testing');
expect(task.isDone, false);
expect(task.time, DateTime.parse("2021-01-12T13:57:10.705476"));
expect(task.priorityValue, 0);
});
}
Related
I have data which I receive from the server. I get through the model in which there is a froJson, toJson method. In the toJson method, I had a problem. When I want to convert the data back to Json, I get an error (I attached a screenshot below). Tell me how can I solve this problem so that everything is fine with the data and I can convert them to Json?
mainModel
class MainModel {
String name;
List<AmenitiesModel>? amenities;
List<DeviceModel>? devices;
List<PhotoModel>? photos;
MainModel ({
required this.name,
this.amenities,
this.devices,
this.photos,
});
factory MainModel .fromJson(Map<String, dynamic> json) =>
MainModel(
id: json['id'],
name: json['name'],
amenities: json['amenities'] != null
? List<AmenitiesModel>.from(
json['amenities'].map(
(item) => AmenitiesModel.fromJson(item),
),
).toList()
: null,
user: json['user'] != null ? User.fromJson(json['user']) : null,
devices: json['devices'] != null
? List<PublicChargingDeviceModel>.from(
json['devices'].map(
(item) => DeviceModel.fromJson(item),
),
).toList()
: null,
photos: json['gallery'] != null
? List<PhotoModel>.from(
json['gallery'].map(
(item) => PhotoModel.fromJson(item),
),
).toList()
: null);
Map<String, dynamic> toJson() {
return {
'name': name,
'amenities': amenities!.map((e) => e.toJson()).toList(),
'devices': devices?.map((e) => e.toJson()).toList(),
'gallery': photos?.map((e) => e.toJson()).toList(),
};
}
amenitiesModel
class AmenitiesModel {
String name;
final String type;
AmenitiesModel({required this.type, required this.name});
factory AmenitiesModel.fromJson(Map<String, dynamic> json) {
return AmenitiesModel(
type: json['type'],
name: json['name'],
);
}
Map<String, dynamic> toJson() {
return {
if (type == 'other') 'name': name,
'type': type,
};
}
Reading map can return null, you can provide default value on null case like
factory AmenitiesModel.fromJson(Map<String, dynamic> json) {
return AmenitiesModel(
type: json['type']??"",
name: json['name']??"",
);
}
I have an error again, but of a different nature. And I can't figure out what the problem is.
The error most likely occurs when I process the response from the server. I do not quite understand, in theory, I receive an object in which there is a list of objects.
The option that does not work for me is suitable for a response from the server in the form of a single object. I thought the same should work with an object, inside which there is a list of objects. I'd like a slightly more detailed answer on this, if possible. Thank you! Code below -
response from server -
models -
class CartModel extends CartEntity {
const CartModel({
required basket,
required delivery,
required idCart,
required total
}) : super (
basket: basket,
delivery: delivery,
idCart: idCart,
total: total
);
factory CartModel.fromJson(Map<String, dynamic> json) {
return CartModel(
basket: json['basket'] != null ? BasketModel.fromJson(json['basket']) : null,
delivery: json['delivery'],
idCart: json['id'],
total: json['total']
);
}
}
class BasketModel extends Basket {
BasketModel({id, images, price, title}) : super(id: id, images: images, price: price, title: title);
factory BasketModel.fromJson(Map<String, dynamic> json) {
return BasketModel(
id: json['id'],
images: json['images'],
price: json['price'],
title: json['title']
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'images': images,
'price': price,
'title': title
};
}
}
request -
Future<List<CartModel>> getAllCart() async {
final response = await client.get(
Uri.parse(ConfigUrl.cart),
headers: {'Content-Type': 'application/json'}
);
if(response.statusCode == 200) {
List<CartModel> result =[];
CartModel cart = CartModel.fromJson(json.decode(response.body));
result.add(cart);
return result;
} else {
throw ServerException();
}
}
Also, if you change the code after checking the status to this -
final cart = json.decode(response.body);
print(cart);
return (cart as List).map((cart) => CartModel.fromJson(cart)).toList();
That error will become -
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of
type 'List' in type cast
And here is the response from the server in the console -
{basket: [{id: 1, images: https://www.manualspdf.ru/thumbs/products/l/1260237-samsung-galaxy-note-20-ultra.jpg, price: 1500, title: Galaxy Note 20 Ultra}, {id: 2, images: https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-13-pro-silver-select?wid=470&hei=556&fmt=jpeg&qlt=95&.v=1631652954000, price: 1800, title: iPhone 13}], delivery: Free, id: 4, total: 3300}
json['basket'] is a List so just map its entries to convert to the object.
class CartModel extends CartEntity {
const CartModel({
required basket,
required delivery,
required idCart,
required total
}) : super (
basket: basket,
delivery: delivery,
idCart: idCart,
total: total
);
factory CartModel.fromJson(Map<String, dynamic> json) {
return CartModel(
// Here
basket: json['basket'] != null
? (json['basket'] as List<dynamic>)
.map((json) => BasketModel.fromJson(json)).toList()
: null;
delivery: json['delivery'],
idCart: json['id'],
total: json['total']
);
}
}
Because your BasketModel expecting Map<String,dynamic> and Firebase sending List.
Try this Basket Model value:
class BasketModel {
List<Basket>? basket;
BasketModel({this.basket});
BasketModel.fromJson(Map<String, dynamic> json) {
if (json['basket'] != null) {
basket = <Basket>[];
json['basket'].forEach((v) {
basket!.add(new Basket.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.basket != null) {
data['basket'] = this.basket!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Basket {
int? id;
String? image;
int? price;
String? title;
Basket({this.id, this.image, this.price, this.title});
Basket.fromJson(Map<String, dynamic> json) {
id = json['id'];
image = json['image'];
price = json['price'];
title = json['title'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['image'] = this.image;
data['price'] = this.price;
data['title'] = this.title;
return data;
}
}
I have a class "DilemmData" whose variables are loaded with data like this:
if (prefs.containsKey('dilemms')) {
MyApp.dilemmList = DilemmData.decode(prefs.getString('dilemms')!);
}
Here is the class:
class DilemmData {
double percent;
final String title;
final String date;
final List<DilemmItemData> plus = [];
final List<DilemmItemData> minus = [];
DilemmData({
plus,
minus,
this.percent = 0,
this.title = '',
this.date = '',
});
static Map<String, dynamic> toJson(DilemmData dilemm) => {
'percent': dilemm.percent,
'title': dilemm.title,
'date': dilemm.date,
'plus': dilemm.plus.map((e) => e.toJson()).toList(),
'minus': dilemm.minus.map((e) => e.toJson()).toList(),
};
factory DilemmData.fromJson(Map<String, dynamic> json) {
print('BOBA: ${json['plus']}');
return DilemmData(
plus: json['plus'],
minus: json['minus'],
percent: json['percent'],
title: json['title'],
date: json['date'],
);
}
static String encode(List<DilemmData> dilemm) => json.encode(
dilemm
.map<Map<String, dynamic>>((dil) => DilemmData.toJson(dil))
.toList(),
);
static List<DilemmData> decode(String dilemm) =>
(json.decode(dilemm) as List<dynamic>)
.map<DilemmData>((dil) => DilemmData.fromJson(dil))
.toList();
}
class DilemmItemData {
final int importance;
final String argument;
DilemmItemData({this.importance = 0, this.argument = ''});
Map<String, dynamic> toJson() {
return {
'importance': importance,
'argument': argument,
};
}
factory DilemmItemData.fromJson(Map<String, dynamic> json) {
return DilemmItemData(
importance: json['importance'], argument: json['argument']);
}
static List<DilemmItemData> decode(String item) =>
(json.decode(item) as List<dynamic>)
.map<DilemmItemData>((dil) => DilemmItemData.fromJson(dil))
.toList();
}
But the plus and minus variables are always empty. Does anyone know how to fix this?
The following code snippet would do the trick. Converting a DilemmItemData from JSON was missing.
factory DilemmData.fromJson(Map<String, dynamic> json) {
return DilemmData(
plus: (json['plus'] as List)
.map((json) => DilemmItemData.fromJson(json))
.toList(),
minus: (json['minus'] as List)
.map((json) => DilemmItemData.fromJson(json))
.toList(),
percent: json['percent'],
title: json['title'],
date: json['date'],
);
}
After update Firebase Realtime Database to 9.0.X I cant converet snapshot.value to Map<dynamic, dynamic> or Map<String, dynamic>
final FirebaseDatabase database = FirebaseDatabase.instance;
database.setPersistenceEnabled(true);
itemRef = database.reference().child('_child1').child(_remoteConfigService.getStringLang);
itemRef.once().then((event) {
final _data1 = Map<String, dynamic>.from(event.snapshot.value as dynamic).forEach((key, value) =>
_notes.add(Item.fromRTDB(value)));
});
My Model Class:
class Item {
String key;
String code;
String spn;
Item({
required this.key,
required this.code,
required this.spn});
factory Item.fromRTDB(Map<String, dynamic> data) {
return Item(
key: data['key'] ?? '01',
code: data['code'] ?? 'A drink',
spn: data['spn'] ?? 'Beer');
}
toJson() {
return {
"key": key,
"code": code,
"spn": spn,
};
}
}
In all options I get error:
List<Object?>' is not a subtype of type 'Map<dynamic, dynamic>'
Seems like the keys in the child are all numbers so it's already a List
Try this:
final _data1 = List.from(event.snapshot.value as dynamic).forEach((key, value) =>
_notes.add(Item.fromRTDB(value)));
Future<Null> getStudies() async {
_data.clear();
DatabaseReference ref = FirebaseDatabase.instance.ref("etudes");
Query query = ref.orderByChild("type").equalTo(1);
// Get the Stream
Stream<DatabaseEvent> stream = query.onValue;
// Subscribe to the stream!
stream.listen((DatabaseEvent event) {
print('Event Type: ${event.type}'); // DatabaseEventType.value;
print('Snapshot: ${event.snapshot}'); // DataSnapshot
if(event.snapshot.exists) {
Map<String, dynamic> data = jsonDecode(jsonEncode(event.snapshot.value)) as Map<String, dynamic>;
data.forEach((key, value) async {
_data.add(Etude.fromJson(value));
});
notifyListeners();
} else {
//print("snapshot does not exists");
_loading = false;
notifyListeners();
}
});
notifyListeners();
return null;
}
i want to use for loop i need "photoThumbnailImagePath" array but i am not able to work on it...! i am trying to get array index of image path but i getting only one image.....! my value is not printing ! i gave u my code and my json data...! plz show me how it works how should i print my image value
if (response.statusCode == 200) {
var jsonResponse = json.decode(response.body);
print("laavvvvvvvvv :" + jsonResponse.toString());
var azim = List<FolderList>.from(jsonResponse["FolderList"].map((x) => FolderList.fromJson(x)));
// ignore: unnecessary_statements
print("printing");
for (final cam in azim){
print("photoThumbnailImagePath:" + cam.photoList[0].photoThumbnailImagePath.toString()); //i am getting here first image only i want all alisting array how
Photlistinng = [cam.photoList[0].photoThumbnailImagePath];
print("Photlistinng : " + Photlistinng.toString());
};
return AllPhotoListing.fromJson(json.decode(response.body));
} else {
// If the server did not return a 201 CREATED response,
// then throw an exception.
throw Exception('Failed to load data');
}
this my my code when api succesful then i use for loop but something wrong with my code so plz check
here is my json data converter
import 'dart:convert';
AllPhotoListing allPhotoListingFromJson(String str) => AllPhotoListing.fromJson(json.decode(str));
String allPhotoListingToJson(AllPhotoListing data) => json.encode(data.toJson());
class AllPhotoListing {
AllPhotoListing({
this.successCode,
this.successMessage,
this.totalPhotos,
this.totalLikes,
this.totalComments,
this.totalShared,
this.totalSelectedPhotosForAlbum,
this.watermarkType,
this.watermarkLogo,
this.watermarkText,
this.watermarkFont,
this.watermarkFontColor,
this.watermarkScaleHeight,
this.watermarkScaleWidth,
this.watermarkOpacity,
this.watermarkFontSize,
this.watermarkPlacement,
this.folderList,
});
String successCode;
String successMessage;
int totalPhotos;
int totalLikes;
int totalComments;
int totalShared;
int totalSelectedPhotosForAlbum;
String watermarkType;
String watermarkLogo;
String watermarkText;
String watermarkFont;
String watermarkFontColor;
int watermarkScaleHeight;
int watermarkScaleWidth;
double watermarkOpacity;
int watermarkFontSize;
String watermarkPlacement;
List<FolderList> folderList;
factory AllPhotoListing.fromJson(Map<String, dynamic> json) => AllPhotoListing(
successCode: json["SuccessCode"],
successMessage: json["SuccessMessage"],
totalPhotos: json["TotalPhotos"],
totalLikes: json["TotalLikes"],
totalComments: json["TotalComments"],
totalShared: json["TotalShared"],
totalSelectedPhotosForAlbum: json["TotalSelectedPhotosForAlbum"],
watermarkType: json["WatermarkType"],
watermarkLogo: json["WatermarkLogo"],
watermarkText: json["WatermarkText"],
watermarkFont: json["WatermarkFont"],
watermarkFontColor: json["WatermarkFontColor"],
watermarkScaleHeight: json["WatermarkScaleHeight"],
watermarkScaleWidth: json["WatermarkScaleWidth"],
watermarkOpacity: json["WatermarkOpacity"].toDouble(),
watermarkFontSize: json["WatermarkFontSize"],
watermarkPlacement: json["WatermarkPlacement"],
folderList: List<FolderList>.from(json["FolderList"].map((x) => FolderList.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"SuccessCode": successCode,
"SuccessMessage": successMessage,
"TotalPhotos": totalPhotos,
"TotalLikes": totalLikes,
"TotalComments": totalComments,
"TotalShared": totalShared,
"TotalSelectedPhotosForAlbum": totalSelectedPhotosForAlbum,
"WatermarkType": watermarkType,
"WatermarkLogo": watermarkLogo,
"WatermarkText": watermarkText,
"WatermarkFont": watermarkFont,
"WatermarkFontColor": watermarkFontColor,
"WatermarkScaleHeight": watermarkScaleHeight,
"WatermarkScaleWidth": watermarkScaleWidth,
"WatermarkOpacity": watermarkOpacity,
"WatermarkFontSize": watermarkFontSize,
"WatermarkPlacement": watermarkPlacement,
"FolderList": List<dynamic>.from(folderList.map((x) => x.toJson())),
};
}
class FolderList {
FolderList({
this.folderId,
this.title,
this.totalCount,
this.photoList,
});
int folderId;
String title;
int totalCount;
List<PhotoList> photoList;
factory FolderList.fromJson(Map<String, dynamic> json) => FolderList(
folderId: json["FolderId"],
title: json["Title"],
totalCount: json["TotalCount"],
photoList: List<PhotoList>.from(json["PhotoList"].map((x) => PhotoList.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"FolderId": folderId,
"Title": title,
"TotalCount": totalCount,
"PhotoList": List<dynamic>.from(photoList.map((x) => x.toJson())),
};
}
class PhotoList {
PhotoList({
this.photoId,
this.photoMainImagePath,
this.photoThumbnailImagePath, // i need this array in my api call
this.photoPreviewImagePath,
this.isSelectedPhoto,
this.isLikedPhoto,
this.photoSelectedCustomers,
this.photoSelectedPhotographerProfile,
});
int photoId;
String photoMainImagePath;
String photoThumbnailImagePath;
String photoPreviewImagePath;
int isSelectedPhoto;
int isLikedPhoto;
List<PhotoSelectedCustomer> photoSelectedCustomers;
String photoSelectedPhotographerProfile;
factory PhotoList.fromJson(Map<String, dynamic> json) => PhotoList(
photoId: json["PhotoId"],
photoMainImagePath: json["PhotoMainImagePath"],
photoThumbnailImagePath: json["PhotoThumbnailImagePath"],
photoPreviewImagePath: json["PhotoPreviewImagePath"],
isSelectedPhoto: json["IsSelectedPhoto"],
isLikedPhoto: json["IsLikedPhoto"],
photoSelectedCustomers: List<PhotoSelectedCustomer>.from(json["PhotoSelectedCustomers"].map((x) =>
PhotoSelectedCustomer.fromJson(x))),
photoSelectedPhotographerProfile: json["PhotoSelectedPhotographerProfile"],
);
Map<String, dynamic> toJson() => {
"PhotoId": photoId,
"PhotoMainImagePath": photoMainImagePath,
"PhotoThumbnailImagePath": photoThumbnailImagePath,
"PhotoPreviewImagePath": photoPreviewImagePath,
"IsSelectedPhoto": isSelectedPhoto,
"IsLikedPhoto": isLikedPhoto,
"PhotoSelectedCustomers": List<dynamic>.from(photoSelectedCustomers.map((x) => x.toJson())),
"PhotoSelectedPhotographerProfile": photoSelectedPhotographerProfile,
};
}
class PhotoSelectedCustomer {
PhotoSelectedCustomer({
this.profilePicture,
});
String profilePicture;
factory PhotoSelectedCustomer.fromJson(Map<String, dynamic> json) => PhotoSelectedCustomer(
profilePicture: json["ProfilePicture"],
);
Map<String, dynamic> toJson() => {
"ProfilePicture": profilePicture,
};
}
you can try this :
for(int i=0; i<azim.length; i++){
//print here
}