I have a FutureBuilder that has no Data. I have this Function to get the Data from the Backend:
Future<List<OrderReceipt>> getOrderReceipt(orderno) async {
final response = await HttpService.order_receipt(orderno);
var decoded = json.decode(response.body)["qry"].cast<Map<String,dynamic>>();
print(decoded);
var OrderR = await decoded.map<OrderReceipt>((json) => OrderReceipt.fromJson(json)).toList();
return OrderR;
}
This is the class with the mapping function:
class OrderReceipt {
final String LUKEBLART;
final String LUKEBLOART;
final String LUKEBLONR;
final String LUKEBLVC;
final String LUKEBLBNR;
final String LUKEBLDRAKT;
final String LUKEBLADS;
final String LUKEBLDATUM;
final String LUKEBLPGM;
final String LUKETIME;
final String LUKESART;
final String LUKEPAGE;
final String LUKELINE;
final String LUKELNR;
final String LUKETXT;
OrderReceipt({
required this.LUKEBLART,
required this.LUKEBLOART,
required this.LUKEBLONR,
required this.LUKEBLVC,
required this.LUKEBLBNR,
required this.LUKEBLDRAKT,
required this.LUKEBLADS,
required this.LUKEBLDATUM,
required this.LUKEBLPGM,
required this.LUKETIME,
required this.LUKESART,
required this.LUKEPAGE,
required this.LUKELINE,
required this.LUKELNR,
required this.LUKETXT,
});
factory OrderReceipt.fromJson(Map<String, dynamic> json) {
return OrderReceipt(
LUKEBLART: json['LUKEBLART'] as String ?? '',
LUKEBLOART: json['LUKEBLOART'] as String ?? '',
LUKEBLONR: json['LUKEBLONR'] as String ?? '',
LUKEBLVC: json['LUKEBLVC'] as String ?? '',
LUKEBLBNR: json['LUKEBLBNR'] as String ?? '',
LUKEBLDRAKT: json['LUKEBLDRAKT'] as String ?? '',
LUKEBLADS: json['LUKEBLADS'] as String ?? '',
LUKEBLDATUM: json['LUKEBLDATUM'] as String ?? '',
LUKEBLPGM: json['LUKEBLPGM'] as String ?? '',
LUKETIME: json['LUKETIME'] as String ?? '',
LUKESART: json['LUKESART'] as String ?? '',
LUKEPAGE: json['LUKEPAGE'] as String ?? '',
LUKELINE: json['LUKELINE'] as String ?? '',
LUKELNR: json['LUKELNR'] as String ?? '',
LUKETXT: json['LUKETX'] as String ?? '',
);}
}
And here is a example of the json (only one dataset):
[{LUKEBLADS: 222222, LUKEBLART: W , LUKEBLBNR: 333333, LUKEBLDATUM: 20230113, LUKEBLDRAKT: FX , LUKEBLOART: FX , LUKEBLONR: 4444, LUKEBLPGM: XXXKG , LUKEBLVC: X1 , LUKELINE: 41, LUKELNR: 36, LUKEPAGE: 1, LUKESART: 1, LUKETIME: Fri, 13 Jan 2023 09:54:02 GMT, LUKETXT: ExampleText USD 66,20 },]
There are a lot of spaces in LUKETXT, because I am generating a .pdf with monospace font (Just for good sizing from the AS400 Database I am working with)
The problem ist in the getOrderReceipt(orderno)
Future, the future prints the decoded
but did not return anything from await decoded.map<OrderReceipt>((json) => OrderReceipt.fromJson(json)).toList();
.
I dont get any error - the FutureBuilder that builds the Future<List<OrderReceipt>>
is processing for like two seconds and then there is no data.
I have two other FutureBuilders in my Project and dont have any problems with them. Does anybody know the error?
Thanks..
EDIT 1:
@Jozott, @Eric Martin and @pmatatias: I have updated the FutureFunction and removed the .cast<Map<String,dynamic>>()
and also the await
but nothing changes in the execution - the error is still there and the function ends by not returning anything from decoded.map<OrderReceipt>((json) => OrderReceipt.fromJson(json)).toList();
- my updated function:
Future<List<OrderReceipt>> getOrderReceipt(orderno) async {
final response = await HttpService.order_receipt(orderno);
print(response);
var decoded = json.decode(response.body)["qry"];
var OrderR = decoded.map<OrderReceipt>((json) => OrderReceipt.fromJson(json)).toList();
print(OrderReceipt);
return OrderR;
}
I also tried to change the factory function to:
...
...
factory OrderReceipt.fromJson(json) {
return OrderReceipt(
...
...
); }
...
...
EDIT 2: This is as talked in the comments the FutureFunction with the try-catch-Block:
Future<List<OrderReceipt>> getOrderReceipt(orderno) async {
try {
final response = await HttpService.order_receipt(orderno);
print(response);
var decoded = json.decode(response.body)["qry"];
var OrderR = decoded.map<OrderReceipt>((json) =>
OrderReceipt.fromJson(json)).toList();
return OrderR;
} catch(err) {
print('Caught error: $err');
throw 'Caught error: $err';
}
}
The following Error is displayed:
type 'null' is not a subtype of type 'string' in type cast
And I also tried to comment out the "LUKETXT" in the Modell - and then it works. Maybe this error can be thrown because there can be dots, colons and other special caracters in the value? -> But as I see in the devtools these special caracters are correctly decoded in the json.decode function to each of them headers and remain a String.
CodePudding user response:
You made a typo in a name field. LUKETX instead of LUKETXT
In your factory :
LUKETXT: json['LUKETX'] as String ?? '',
Your code try to cast null value to a string. That's why you get this error.
As @jozott mentionned, you can use a code generator code like json_serializable to avoid typos : https://pub.dev/packages/json_serializable
By the way, i don't think you have to declare the cast "as string" because dart infers the type. Imagine a String field name, you can write this :
User.fromJson(Map<String, dynamic> json)
: name = json['name'] ?? ''