Flutter Hive data - flutter

I am writing data to a Hive box in flutter using the following data from an API;
{
"deliveryAddresses": [
{
"deliveryAddressNo": "1130119",
"deliveryAddressName": "AIRCRAFT MOVEMENTS 2169 (EAA)",
"pointOfServices": [
{
"deliveryAddressNo": "1130119",
"pointOfServiceNo": "1",
"pointOfServiceName": "HT54505",
"pointOfServiceDescription": ""
},
{
"deliveryAddressNo": "1130119",
"pointOfServiceNo": "2",
"pointOfServiceName": "WASH BAY",
"pointOfServiceDescription": ""
}
]
},
{
"deliveryAddressNo": "1130147",
"deliveryAddressName": "TESCO - 6144 - HARROW APOLLO",
"pointOfServices": [
{
"deliveryAddressNo": "1130147",
"pointOfServiceNo": "1",
"pointOfServiceName": "ACTE711092",
"pointOfServiceDescription": ""
}
]
}
]
}
The data is showing in the Box as i expect however, the 2 pointOfServices for the first account show in the Box as NULL. The 2nd customers pointOfService gets written OK.
Any ideas? Is it because there's 2 sets of data on the first account?
Edited:
Showing my Model code for deliveryAddresses;
List<Order> orderListFromJson(String val) => List<Order>.from(json
.decode(val)['deliveryAddresses']
.map((val) => Order.orderInfofromJson(val)));
#HiveType(typeId: 0)
class Order extends HiveObject {
#HiveField(0)
String? deliveryAddressNo;
#HiveField(1)
String? deliveryAddressName;
#HiveField(2)
List<PointOfServices>? pointOfServices;
Order(
{this.deliveryAddressNo, this.deliveryAddressName, this.pointOfServices});
factory Order.orderInfofromJson(Map<String, dynamic> deliveryAddresses) =>
Order(
deliveryAddressNo: deliveryAddresses['deliveryAddressNo'],
deliveryAddressName: deliveryAddresses['deliveryAddressName'],
pointOfServices: List<PointOfServices>.from(
deliveryAddresses['pointOfServices']
.map((pos) => PointOfServices.fromJson(pos))));
}
Points of service model;
List<PointOfServices> posListFromJson(String val) =>
List<PointOfServices>.from(json
.decode(val)['pointOfServices']
.map((val) => PointOfServices.fromJson(val)));
#HiveType(typeId: 1)
class PointOfServices {
#HiveField(7)
String? deliveryAddressNo;
#HiveField(8)
String? pointOfServiceNo;
#HiveField(9)
String? pointOfServiceName;
#HiveField(10)
String? pointOfServiceDescription;
PointOfServices(
{this.deliveryAddressNo,
this.pointOfServiceNo,
this.pointOfServiceName,
this.pointOfServiceDescription});
factory PointOfServices.fromJson(Map<String, dynamic> pointOfServices) =>
PointOfServices(
deliveryAddressNo: pointOfServices['deliveryAddressNo'],
pointOfServiceNo: pointOfServices['pointOfServiceNo'],
pointOfServiceName: pointOfServices['pointOfServiceName'],
pointOfServiceDescription:
pointOfServices['pointOfServiceDescription']);
}
Code that builds the the data and adds to the box;
if (!Hive.isBoxOpen(orderInfoBox)) {
_orderInfo = await Hive.openBox<Order>('orderInfo_db');
_orderInfo.clear();
var result = await OrderNetwork().get();
var resultBody = await json.decode(json.encode(result.body));
List<Order> orderList = List<Order>.empty(growable: true);
orderList.addAll(orderListFromJson(resultBody));
_orderInfo.addAll(orderList);

Related

how to filter data based on tag in flutter?

I am creating a screen where need to filter data based on category types and transaction type.
Its working fine but it results null when filter list is empty, I can manage with some logically tricks but it will be lengthy coding..
is there any other better way to filter data properly even if filter tag is empty and
should display all records based on transaction type
like
transactiontype='Expense'
filtertags=[]
result:
it should display all expense transactions
transactiontype='Expense'
filtertags=['Food']
result:
it should display all expense transactions of Food
class TransactionModel {
String category;
double amount;
bool isExpense;
TransactionModel(
{required this.category, required this.amount, this.isExpense = true});
String printData() {
return 'Category:' +
category +
' Amount: ' +
amount.toString() +
'isExpense:' +
isExpense.toString();
}
}
List<String> _filtertags = ['Food'];// if this list is empty it should show all posible records
String transactiontype = 'Expense';
List<TransactionModel> transactions = [
TransactionModel(
category: 'Shopping',
amount: 4300,
),
TransactionModel(category: 'Food', amount: 2200,isExpense: true),
TransactionModel(category: 'Loan', amount: 400, isExpense: false),
TransactionModel(category: 'Food', amount: 300,isExpense: false),
TransactionModel(category: 'Other', amount: 100,isExpense: true),
];
void main() {
var resultdata = transactiontype == 'All'
? transactions
.where((element) => _filtertags.contains(element.category))
.toList()
: transactiontype == 'Expense'
? transactions
.where((element) =>
_filtertags.contains(element.category) &&
element.isExpense == true)
.toList()
: transactions
.where((element) =>
_filtertags.contains(element.category) &&
element.isExpense == false)
.toList();
for (var x in resultdata) {
print(x.printData());
}
}
You can simplify like
var result = [];
if (transactionType == 'All' || transactionType.isEmpty) {
result = transactions.toList();
} else {
bool isExpense = transactionType == 'Expense';
//add more filter when needed and comare with model class
result = transactions
.where((element) =>
_filterTags.contains(element.category) &&
element.isExpense == isExpense)
.toList();
}
for (var x in result) {
print(x.toString());
}
});

How to select the desired elements in a list in Dart, and change the data of this element

I have an array with such data (more data in reality)
[
{
serviceid: "979cf8e6",
amount: 1,
price: 0,
materialsPrice: 100,
enable: true,
chenge: true
},
{
serviceid: "979cf812",
amount: 1,
price: 15.5,
materialsPrice: 0,
enable: true,
chenge: false
}
]
My goal is to change "enable" to the desired status in the selected element of the array. For this I will use a block. That is, if when I click on the event, I transfer (false and "979cf8e6") . Then the required element should be found (service = 979cf8e6). And this element should have enable on false. I tried to start something, but it didn't work. Maybe someone knows how to do it?))
on<OnChangeStatusListItemClick>((event, emit) async {
var serviceId = event.serviceId;//(my serviceId here)
var paymentStatus = event.status;//(my new status here)
var paymentDetails = state.listVariant; //(my list here)
PaymentDetailsModel? selected;
paymentDetails = paymentDetails.map((paymentDetailsOne) {
paymentDetailsOne.serviceid == serviceId;
var selectedPaymentDetails = paymentDetailsOne.copyWith(enable: paymentStatus);
return selectedPaymentDetails;
}).toList();
emit(state.copyWith(listVariant: paymentDetails));
});
My PaymentDetailsModel model (this model is used in listVariant)
#freezed
class PaymentDetailsModel with _$PaymentDetailsModel {
#JsonSerializable(fieldRename: FieldRename.none, explicitToJson: true)
const factory PaymentDetailsModel({
required String serviceid,
required double? price,
required int? minmal,
required int amount,
required bool enable,
required bool chenge,
}) = _PaymentDetailsModel;
factory PaymentDetailsModel.fromJson(Map<String, dynamic> json) =>
_$PaymentDetailsModelFromJson(json);
}
I think maybe you miss if else check in your map function, not pretty sure, but you can try :
on<OnChangeStatusListItemClick>((event, emit) async {
final serviceId = event.serviceId;//(my serviceId here)
final paymentStatus = event.status;//(my new status here)
final paymentDetails = state.listVariant.map((paymentDetailsOne) {
if ( paymentDetailsOne.serviceid == serviceId) {
return paymentDetailsOne.copyWith(enable: paymentStatus);
} else {
return paymentDetailsOne;
}
}).toList();
emit(state.copyWith(listVariant: paymentDetails));
});

Dart - How to merge two list of objects into singe list

2> as you can see below i have two list of object and i want to merge into single it should compare list based on date
//here is the list 1
List<Object1> list1=[
Object1("date":"1","day_data":12),
Object1("date":"2","day_data":15),
]
//here is the list 2
List<Object2> list2=[
Object2("date":"1","night_data":56),
Object2("date":"3","night_data":80),
];
//expected output
List<Object3> expectedList=[
Object3("date":"1","day_data":12,"night_data":56),
Object3("date":"2","day_data":15,"night_data":null),
Object3("date":"3","day_data":null,"night_data":80),
];
The code below should do the trick. It uses a Map where the keys are, let's say, the Primary Key. And the values are the reduce from list1 and list2 (It even merges duplicated items by date from list1 and/or list2). At the end, I've added some asserts to actually test if it works.
Here's also the DartPad to run it online.
class Object1 {
final String date;
final int day_data;
const Object1({required this.date, required this.day_data});
}
class Object2 {
final String date;
final int night_data;
const Object2({required this.date, required this.night_data});
}
class Object3 {
final String date;
final int? day_data;
final int? night_data;
const Object3({required this.date, this.day_data, this.night_data});
}
List<Object3> merge(List<Object1> obj1List, List<Object2> obj2List) {
final map = <String, Object3>{};
obj1List.forEach((obj1) =>
map.update(
obj1.date,
(obj3) => Object3(date: obj3.date, day_data: obj1.day_data, night_data: obj3.night_data),
ifAbsent: () => Object3(date: obj1.date, day_data: obj1.day_data, night_data: null),
));
obj2List.forEach((obj2) =>
map.update(
obj2.date,
(obj3) => Object3(date: obj3.date, day_data: obj3.day_data, night_data: obj2.night_data),
ifAbsent: () => Object3(date: obj2.date, day_data: null, night_data: obj2.night_data),
));
return map.values.toList()
..sort((a, b) => a.date.compareTo(b.date));
}
void main() {
//here is the list 1
List<Object1> list1=[
Object1(date:"1",day_data:12),
Object1(date:"2",day_data:15),
];
//here is the list 2
List<Object2> list2=[
Object2(date:"1",night_data:56),
Object2(date:"3",night_data:80),
];
List<Object3> actualList = merge(list1, list2);
//expected output
List<Object3> expectedList=[
Object3(date:"1",day_data:12,night_data:56),
Object3(date:"2",day_data:15,night_data:null),
Object3(date:"3",day_data:null,night_data:80),
];
print('Checking size...');
assert(actualList.length == expectedList.length);
print('OK');
print('Checking items...');
actualList.asMap().forEach((i, actual) {
final expected = expectedList[i];
print(' Checking item $i...');
assert(actual.date == expected.date);
assert(actual.day_data == expected.day_data);
assert(actual.night_data == expected.night_data);
print(' OK');
});
print('OK');
}
You need to do manually with two loops and comparing dates.
Hey you can achieve by compering two list and get list like below -
void compareList(){
List<ObjectModel> list1=[
ObjectModel(date:"1",dayData:12),
ObjectModel(date:"2",dayData:15),
];
//here is the list 2
List<ObjectModel> list2=[
ObjectModel(date:"1",nightData:56),
ObjectModel(date:"3",nightData:80),
];
//expected output
List<ObjectModel> expectedList= [];
list1.forEach((element) {
ObjectModel innerObject = list2.firstWhere((ObjectModel innerElement) => element.date == innerElement.date, orElse: (){return ObjectModel();});
if(innerObject.date !=null){
expectedList.add(ObjectModel(date:element.date,dayData:element.dayData,nightData: innerObject.nightData));
}else{
expectedList.add(element);
}
});
list2.forEach((element) {
ObjectModel innerObject = list1.firstWhere((ObjectModel innerElement) => element.date == innerElement.date, orElse: (){return ObjectModel();});
if(innerObject.date ==null){
expectedList.add(element);
}
});
print(expectedList.length);
}
class ObjectModel{
String? date;
int? dayData;
int? nightData;
ObjectModel({ this.date, this.dayData, this.nightData});
}

Not properly mapping values in Dart model

I know I am not properly mapping values when it comes to make a GET request since I am getting a null response.
Specifically I know the problem it is the fields "Behavior" and "Description" since they are lists and are more complex to map for me. Before adding these two fields the mapping was done properly and I was able to get the proper response.
my fetchdata function:
fetchData(url) async {
var client = http.Client();
final response = await client.get(Uri.parse(url));
if (response.statusCode == 200) {
var jsonDecoded = json.decode(response.body);
BreedList = jsonDecoded.map((data) => DogClass.fromJson(data)).toList();
return jsonDecoded;
} else {
throw Exception('Failed to load data');
}
}
Here I am attaching my data model.
class DogClass {
Id? _iId;
String? _breed;
String? _origin;
String? _url;
String? _img;
List<Behavior>? _behavior;
List<Description>? _description;
final _descriptionlist = <Description>[];
DogClass(
{Id? iId,
String? breed,
String? origin,
String? url,
String? img,
List<Behavior>? behavior,
List<Description>? description}) {
if (iId != null) {
this._iId = iId;
}
if (breed != null) {
this._breed = breed;
}
if (origin != null) {
this._origin = origin;
}
if (url != null) {
this._url = url;
}
if (img != null) {
this._img = img;
}
if (behavior != null) {
this._behavior = behavior;
}
if (description != null) {
this._description = description;
}
}
Id? get iId => _iId;
set iId(Id? iId) => _iId = iId;
String? get breed => _breed;
set breed(String? breed) => _breed = breed;
String? get origin => _origin;
set origin(String? origin) => _origin = origin;
String? get url => _url;
set url(String? url) => _url = url;
String? get img => _img;
set img(String? img) => _img = img;
List<Behavior>? get behavior => _behavior;
set behavior(List<Behavior>? behavior) => _behavior = behavior;
List<Description>? get description => _description;
set description(List<Description>? description) => _description = description;
factory DogClass.fromJson(Map<String, dynamic> json) {
return DogClass(
iId: json['_id'] != null ? Id.fromJson(json['_id']) : null,
breed: json['breed'],
origin: json['origin'],
url: json['url'],
img: json['img'],
behavior: (json['behavior'] as List).cast<Behavior>(),
description: (json['Description'] as List).cast<Description>());
}
}
class Id {
String? _oid;
Id({String? oid}) {
if (oid != null) {
this._oid = oid;
}
}
String? get oid => _oid;
set oid(String? oid) => _oid = oid;
Id.fromJson(Map<String, dynamic> json) {
_oid = json['$oid'];
}
}
class Behavior {
Id? _iId;
String? _imageLink;
int? _goodWithChildren;
int? _goodWithOtherDogs;
int? _shedding;
int? _grooming;
int? _drooling;
int? _coatLength;
int? _goodWithStrangers;
int? _playfulness;
int? _protectiveness;
int? _trainability;
int? _energy;
int? _barking;
int? _minLifeExpectancy;
int? _maxLifeExpectancy;
double? _maxHeightMale;
double? _maxHeightFemale;
int? _maxWeightMale;
int? _maxWeightFemale;
int? _minHeightMale;
int? _minHeightFemale;
int? _minWeightMale;
int? _minWeightFemale;
String? _breed;
Behavior(
{Id? iId,
String? imageLink,
int? goodWithChildren,
int? goodWithOtherDogs,
int? shedding,
int? grooming,
int? drooling,
int? coatLength,
int? goodWithStrangers,
int? playfulness,
int? protectiveness,
int? trainability,
int? energy,
int? barking,
int? minLifeExpectancy,
int? maxLifeExpectancy,
double? maxHeightMale,
double? maxHeightFemale,
int? maxWeightMale,
int? maxWeightFemale,
int? minHeightMale,
int? minHeightFemale,
int? minWeightMale,
int? minWeightFemale,
String? breed}) {
if (iId != null) {
this._iId = iId;
}
if (imageLink != null) {
this._imageLink = imageLink;
}
if (goodWithChildren != null) {
this._goodWithChildren = goodWithChildren;
}
if (goodWithOtherDogs != null) {
this._goodWithOtherDogs = goodWithOtherDogs;
}
if (shedding != null) {
this._shedding = shedding;
}
if (grooming != null) {
this._grooming = grooming;
}
if (drooling != null) {
this._drooling = drooling;
}
if (coatLength != null) {
this._coatLength = coatLength;
}
if (goodWithStrangers != null) {
this._goodWithStrangers = goodWithStrangers;
}
if (playfulness != null) {
this._playfulness = playfulness;
}
if (protectiveness != null) {
this._protectiveness = protectiveness;
}
if (trainability != null) {
this._trainability = trainability;
}
if (energy != null) {
this._energy = energy;
}
if (barking != null) {
this._barking = barking;
}
if (minLifeExpectancy != null) {
this._minLifeExpectancy = minLifeExpectancy;
}
if (maxLifeExpectancy != null) {
this._maxLifeExpectancy = maxLifeExpectancy;
}
if (maxHeightMale != null) {
this._maxHeightMale = maxHeightMale;
}
if (maxHeightFemale != null) {
this._maxHeightFemale = maxHeightFemale;
}
if (maxWeightMale != null) {
this._maxWeightMale = maxWeightMale;
}
if (maxWeightFemale != null) {
this._maxWeightFemale = maxWeightFemale;
}
if (minHeightMale != null) {
this._minHeightMale = minHeightMale;
}
if (minHeightFemale != null) {
this._minHeightFemale = minHeightFemale;
}
if (minWeightMale != null) {
this._minWeightMale = minWeightMale;
}
if (minWeightFemale != null) {
this._minWeightFemale = minWeightFemale;
}
if (breed != null) {
this._breed = breed;
}
}
Id? get iId => _iId;
set iId(Id? iId) => _iId = iId;
String? get imageLink => _imageLink;
set imageLink(String? imageLink) => _imageLink = imageLink;
int? get goodWithChildren => _goodWithChildren;
set goodWithChildren(int? goodWithChildren) =>
_goodWithChildren = goodWithChildren;
int? get goodWithOtherDogs => _goodWithOtherDogs;
set goodWithOtherDogs(int? goodWithOtherDogs) =>
_goodWithOtherDogs = goodWithOtherDogs;
int? get shedding => _shedding;
set shedding(int? shedding) => _shedding = shedding;
int? get grooming => _grooming;
set grooming(int? grooming) => _grooming = grooming;
int? get drooling => _drooling;
set drooling(int? drooling) => _drooling = drooling;
int? get coatLength => _coatLength;
set coatLength(int? coatLength) => _coatLength = coatLength;
int? get goodWithStrangers => _goodWithStrangers;
set goodWithStrangers(int? goodWithStrangers) =>
_goodWithStrangers = goodWithStrangers;
int? get playfulness => _playfulness;
set playfulness(int? playfulness) => _playfulness = playfulness;
int? get protectiveness => _protectiveness;
set protectiveness(int? protectiveness) => _protectiveness = protectiveness;
int? get trainability => _trainability;
set trainability(int? trainability) => _trainability = trainability;
int? get energy => _energy;
set energy(int? energy) => _energy = energy;
int? get barking => _barking;
set barking(int? barking) => _barking = barking;
int? get minLifeExpectancy => _minLifeExpectancy;
set minLifeExpectancy(int? minLifeExpectancy) =>
_minLifeExpectancy = minLifeExpectancy;
int? get maxLifeExpectancy => _maxLifeExpectancy;
set maxLifeExpectancy(int? maxLifeExpectancy) =>
_maxLifeExpectancy = maxLifeExpectancy;
double? get maxHeightMale => _maxHeightMale;
set maxHeightMale(double? maxHeightMale) => _maxHeightMale = maxHeightMale;
double? get maxHeightFemale => _maxHeightFemale;
set maxHeightFemale(double? maxHeightFemale) =>
_maxHeightFemale = maxHeightFemale;
int? get maxWeightMale => _maxWeightMale;
set maxWeightMale(int? maxWeightMale) => _maxWeightMale = maxWeightMale;
int? get maxWeightFemale => _maxWeightFemale;
set maxWeightFemale(int? maxWeightFemale) =>
_maxWeightFemale = maxWeightFemale;
int? get minHeightMale => _minHeightMale;
set minHeightMale(int? minHeightMale) => _minHeightMale = minHeightMale;
int? get minHeightFemale => _minHeightFemale;
set minHeightFemale(int? minHeightFemale) =>
_minHeightFemale = minHeightFemale;
int? get minWeightMale => _minWeightMale;
set minWeightMale(int? minWeightMale) => _minWeightMale = minWeightMale;
int? get minWeightFemale => _minWeightFemale;
set minWeightFemale(int? minWeightFemale) =>
_minWeightFemale = minWeightFemale;
String? get breed => _breed;
set breed(String? breed) => _breed = breed;
factory Behavior.fromJson(Map<String, dynamic> json) {
return Behavior(
iId : json['_id'] != null ? Id.fromJson(json['_id']) : null,
imageLink : json['image_link'],
goodWithChildren : json['good_with_children'],
goodWithOtherDogs : json['good_with_other_dogs'],
shedding : json['shedding'],
grooming : json['grooming'],
drooling : json['drooling'],
coatLength : json['coat_length'],
goodWithStrangers : json['good_with_strangers'],
playfulness : json['playfulness'],
protectiveness : json['protectiveness'],
trainability : json['trainability'],
energy : json['energy'],
barking : json['barking'],
minLifeExpectancy : json['min_life_expectancy'],
maxLifeExpectancy : json['max_life_expectancy'],
maxHeightMale : json['max_height_male'],
maxHeightFemale : json['max_height_female'],
maxWeightMale : json['max_weight_male'],
maxWeightFemale : json['max_weight_female'],
minHeightMale : json['min_height_male'],
minHeightFemale : json['min_height_female'],
minWeightMale : json['min_weight_male'],
minWeightFemale : json['min_weight_female'],
breed : json['breed']
);}
}
class Description {
Id? iId;
String? breed;
String? contenido;
Description({this.iId, this.breed, this.contenido});
factory Description.fromJson(Map<String, dynamic> json) {
return Description(
iId: json['_id'] != null ? Id.fromJson(json['_id']) : null,
breed: json['breed'],
contenido: json['contenido'],
);
}
}
Here's is my json content:
[{"_id": {"$oid": "625f2900fe6aeb351381c3f5"}, "breed": "Africanis", "origin": "Southern Africa", "url": "https://en.wikipedia.org/wiki/Af", "img": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/", "behavior": [], "Description": [{"_id": {"$oid": "626829de7103fd0096bd5dd8"}, "breed": "Africanis", "contenido": "Some content"}]}
Any help would be really appreciated.
I prefer you to use a vs code tool to easily make a dart data model
Name: Json to Dart Model
VS Marketplace Link:
https://marketplace.visualstudio.com/items?itemName=hirantha.json-to-dart
Here is the model code, You just pass GET response data through it
class DogClass {
Id? id;
String? breed;
String? origin;
String? url;
String? img;
List<dynamic>? behavior;
List<Description>? description;
DogClass({
this.id,
this.breed,
this.origin,
this.url,
this.img,
this.behavior,
this.description,
});
factory DogClass.fromMap(Map<String, dynamic> data) => DogClass(
id: data['_id'] == null
? null
: Id.fromMap(data['_id'] as Map<String, dynamic>),
breed: data['breed'] as String?,
origin: data['origin'] as String?,
url: data['url'] as String?,
img: data['img'] as String?,
behavior: data['behavior'] as List<dynamic>?,
description: (data['Description'] as List<dynamic>?)
?.map((e) => Description.fromMap(e as Map<String, dynamic>))
.toList(),
);
}
/// id DogClass class
///
class Id {
String? oid;
Id({this.oid});
factory Id.fromMap(Map<String, dynamic> data) => Id(
oid: data['\$oid'] as String?,
);
}
// description class DogClass
//
class Description {
Id? id;
String? breed;
String? contenido;
Description({this.id, this.breed, this.contenido});
factory Description.fromMap(Map<String, dynamic> data) => Description(
id: data['_id'] == null
? null
: Id.fromMap(data['_id'] as Map<String, dynamic>),
breed: data['breed'] as String?,
contenido: data['contenido'] as String?,
);
}

Rest API Consumption in flutter

Problem
I'm trying to receive data from a rest API in my flutter app, inside a future function but i keep getting the following error:
type 'CastList<dynamic, List>' is not a subtype of type 'List'.
The function I'm using to fetch the data is as follows:
static Future<List<Questionnaire>> fetchQuestionnaires() async {
try {
final response =
await http.get('http://10.0.2.2:4010/phone/questionnaires');
if (response.statusCode == 200) {
List<Questionnaire> resp =
json.decode(response.body).cast<List<Questionnaire>>();
List<Questionnaire> questionnaires = resp
.map<Questionnaire>((dynamic item) => Questionnaire.fromJson(item))
.toList();
log(
questionnaires.toString(),
);
return questionnaires;
} else {
throw Exception('Unable to fetch questionnaires');
}
} catch (error) {
log(error.toString());
}
}
I don't understand why this is. Why does using cast, cast to CastList<dynamic, Type> and not the original Type? What changes do I do to get my data?
The data model is given below.
Data Model
The Data i expect from my backend is like this. An array called questionnaires, containing multiples of a questionnaire, each containing an id and a displayQuestion. A displayQuestion in turn has the question text and the answers Array_.
For this, I have the following structure in my Json.
[
{
"questionId": 1,
"displayQuestions": [
{
"question": "how old are you",
"answers": [
"1",
"2",
"3",
"4"
]
}
]
}
]
This is my questionnaires.dart model
class Questionnaires {
List<Questionnaire> _questionnaires;
Questionnaires.fromJson(this._questionnaires);
}
This is questionnaire.dart model
class Questionnaire {
int questionnaireId;
List<DisplayQuestion> displayQuestions = [];
Questionnaire(this.questionnaireId, this.displayQuestions);
Questionnaire.fromJson(Map<String, dynamic> json)
: questionnaireId = json['questionnaireId'],
displayQuestions = json['displayQuestions'];
}
The code from display-question.dart model
class DisplayQuestion {
String _question;
List<String> _answers;
String get question => this._question;
List get answers => this._answers;
DisplayQuestion(this._question, [List<String> answers])
: this._answers = answers ?? [];
DisplayQuestion.fromJson(Map<String, dynamic> json)
: _question = json['question'],
_answers = json['answers'];
}
Why does using cast, cast to CastList<dynamic, Type> and not the original Type?
From the docs, myList.cast<MyType> returns a List<MyType>. In your case you're calling resp.cast<List<Questionnaire>>, so the return will be List<List<Questionnaire>>, which is not what you want.
If you're asking about CastList<dynamic, Type>, it's a subclass of List<Type>, see the source code. It's useful because CastList doesn't need to create a new list, it's just a wrapper around the original list where each element is cast with as Type before being returned.
What changes do I do to get my data?
The problem is you're calling resp.cast<Type> where resp is not a list that constains Type.
Here's a working sample based on the code you provided:
import 'dart:convert';
final sampleJson = """[
{
"questionId": 1,
"displayQuestions": [
{
"question": "how old are you",
"answers": [
"1",
"2",
"3",
"4"
]
}
]
}
]
""";
class DisplayQuestion {
String question;
List<String> answers;
DisplayQuestion.fromJson(Map<String, dynamic> json)
: question = json["question"],
answers = json["answers"].cast<String>();
String toString() => 'question: $question | answers: $answers';
}
class Questionnaire {
int questionnaireId;
List<DisplayQuestion> displayQuestions;
Questionnaire.fromJson(Map<String, dynamic> json)
: questionnaireId = json['questionnaireId'],
displayQuestions = (json['displayQuestions'] as List<dynamic>)
.map((questionJson) => DisplayQuestion.fromJson(questionJson))
.toList();
String toString() => '$displayQuestions';
}
List<Questionnaire> parseQuestionnaires() {
List<Questionnaire> questionnaires =
(json.decode(sampleJson) as List<dynamic>)
.map((questionnaireJson) => Questionnaire.fromJson(questionnaireJson))
.toList();
return questionnaires;
}
void main() {
print(parseQuestionnaires());
// => [[question: how old are you | answers: [1, 2, 3, 4]]]
}