How to use polymorphism in dart - flutter

Hi I need to use polymorphism in flutter to use it in get data from Restfull API
but it doesn't work.
first I have a base class (Model)
class Model
{
Model();
Model.fromJson(Map<String, dynamic> json) ;
Map<String, dynamic> toJson(){}
}
then I have derived class (City)
class City extends Model {
int id;
String name;
List<Region> regions;
City({this.id, this.name, this.regions});
City.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
if (json['regions'] != null) {
regions = new List<Region>();
json['regions'].forEach((v) {
regions.add(new Region.fromJson(v));
});
}
}
}
and this is a function with getAllModel method
class Repository
{
static Future<List<T>> getAllModel<T extends Model>( apis url) async {
try {
bool tk = await Cache.tokenExists();
if (tk) {
String token = await Cache.getString(keys.api_token);
var body = {};
List<dynamic> data = await Request.callAPI(
apiName.name(url),
body,
method: 'GET', apiToken: token);
List<T> objs = new List();
if (data != null) if (data.length > 0) {
data.forEach((v) {
T r = Model.fromJson(v) as T;
objs.add(r);
});
return objs;
}
return objs;
}
return new List();
} catch (e, stacktrace) {
print("getAll() | catch exception");
print(e);
print(stacktrace);
return new List();
}
}
}
finally this is a call method
static Future<List<City>> getCities() async {
return Repository.getAllModel(apis.getCities);
}
this is a problem
type 'Model' is not a subtype of type 'City' in type cast
How can I solve this ?

Model.fromJson(v) will always return a value of the base type, Model.
You can't cast this to T = City here:
T r = Model.fromJson(v) as T;
because Dart can't know how to turn a Model into a City.
You would want to call “T.fromJson(v)”, so to speak, but Dart doesn't allow us to speak polymorphically about constructors.
I think your best bet might be to pass the relevant fromJson function along to getAllModel:
// The type of functions that take a JSON map and return T.
typedef JsonDecoder<T> = T Function(Map<String, dynamic> json);
// Use a provided `fromJson` callback to transform your API results:
Future<List<T>> getAllModel<T extends Model>(String url,
JsonDecoder<T> fromJson) async {
...
T r = fromJson(v);
...
}
// And provide it like so:
void myFunction() {
final cities = await getAllModel<City>("city url", (j) => City.fromJson(j));
}
(Somewhat annoyingly, we can't even write this:)
getAllModel<City>("city url", City.fromJson);
^^^^^^^^^^^^^
By the way, I recommend looking into json_serializable.

Here is an aproach i am thinking of taking to render different components returned from a REST api (strapi)
I want to render the components based on type from a response like this
{
"data": {
"id": 1,
"homepage": [
{
"id": 1,
"__component": "explore.search",
"enabled": true,
"include_articles": true,
"include_menu_entries": true,
"include_contributors": true
},
{
"id": 1,
"__component": "explore.whats-new",
"entry_count": 7
}
]
},
"meta": {}
}
I created a base component model like this to capture the common parameters to be extended by each component model later
class CmsComponent {
CmsComponent({
required this.id,
required this.component,
});
int id;
String component;
factory CmsComponent.fromJson(Map<String, dynamic> json) => CmsComponent(
id: json["id"],
component: json["__component"],
);
Map<String, dynamic> toJson() => {
"id": id,
"__component": component,
};
}
then an example of a single component model is
class CmsComponentSearch extends CmsComponent{
CmsComponentSearch({
required id,
required component,
required this.enabled,
required this.includeArticles,
required this.includeMenuEntries,
required this.includeContributors,
}) : super(id: id, component: component);
bool enabled;
bool includeArticles;
bool includeMenuEntries;
bool includeContributors;
factory CmsComponentSearch.fromJson(Map<String, dynamic> json) => CmsComponentSearch(
id: json["id"],
component: json["__component"],
enabled: json["enabled"],
includeArticles: json["include_articles"],
includeMenuEntries: json["include_menu_entries"],
includeContributors: json["include_contributors"],
);
Map<String, dynamic> toJson() => {
"id": id,
"__component": component,
"enabled": enabled,
"include_articles": includeArticles,
"include_menu_entries": includeMenuEntries,
"include_contributors": includeContributors,
};
}
then at the top level i can create this model with a method to switch out each components model as needed
class CmsExploreHome {
CmsExploreHome({
required this.id,
required this.components,
});
int id;
List<dynamic> components;
factory CmsExploreHome.fromJson(Map<String, dynamic> json) => CmsExploreHome(
id: json["id"],
components: List<dynamic>.from(json["homepage"].map((x) => getCmsComponentModelFromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"homepage": List<dynamic>.from(components.map((x) => x.toJson())),
};
}
getCmsComponentModelFromJson(Map<String, dynamic> json) {
switch(json['__component']) {
case 'explore.search' : return CmsComponentSearch.fromJson(json);
case 'explore.whats-new' : return CmsComponentWhatsNew.fromJson(json);
default : return CmsComponent.fromJson(json);
}
}
Thats the data modelling done, then in the UI widget i can do something like this
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('explore'),
for (var component in exploreProvider.cmsExploreHome!.components) _RenderComponent(component),
],
),
and add the following widgets
class _RenderComponent extends StatelessWidget {
const _RenderComponent(this.component, {Key? key}) : super(key: key);
final CmsComponent component;
#override
Widget build(BuildContext context) {
if(component is CmsComponentSearch) return CmsSearchComponent(component as CmsComponentSearch);
return Text("${component.component} not implemented");
}
}
and for example
class CmsSearchComponent extends StatelessWidget {
const CmsSearchComponent(this.component, {Key? key}) : super(key: key);
final CmsComponentSearch component;
#override
Widget build(BuildContext context) {
return Text("Search field");
}
}
That gets the job done, the flutter app can receive dynamic types from the REST api in a list and render them

Related

A value of type 'Iterable<HospitalListModel>' can't be assigned to a variable of type 'List<HospitalListModel>'

I got a flutter error A value of type 'Iterable<HospitalListModel>' can't be assigned to a variable of type 'List<HospitalListModel>'. This is my model:
List<HospitalListModel> hospitalListModelFromJson(String str) => List<HospitalListModel>.from(json.decode(str).map((x) => HospitalListModel.fromJson(x)));
String hospitalListModelToJson(List<HospitalListModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class HospitalListModel {
HospitalListModel({
this.id,
this.title,
this.content,
this.image,
this.phone,
this.coordinates,
this.website,
this.createdAt,
this.updatedAt,
});
dynamic id;
dynamic title;
dynamic content;
dynamic image;
dynamic phone;
dynamic coordinates;
dynamic website;
dynamic createdAt;
dynamic updatedAt;
factory HospitalListModel.fromJson(Map<String, dynamic> json) => HospitalListModel(
id: json["id"],
title: json["title"],
content: json["content"],
image: json["image"],
phone: json["phone"],
coordinates: json["coordinates"],
website: json["website"],
createdAt: json["created_at"],
updatedAt: json["updated_at"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"content": content,
"image": image,
"phone": phone,
"coordinates": coordinates,
"website": website,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
and this is where the error come from, it's from the API provider and im confused why it throw iterable
class ApiProvider {
final Dio _dio = Dio();
final String _url = 'http://lovemonster.my.id/hospital';
Future<List<HospitalListModel>> fetchHospitalList() async {
try {
List<HospitalListModel> hospitalList = [];
Response response = await _dio.get(_url);
var mData = response.data as List;
hospitalList = mData.
map<HospitalListModel>((e) => hospitalListModelFromJson(e)
.toList();
return hospitalList;//return List not object
} catch (error, stacktrace) {
print("Exception occurred: $error stackTrace: $stacktrace");
return Future.error("");
}
}
}
hospitalList = mData.map<HospitalListModel>((e) =>hospitalListModelFromJson(e).toList();this code throw an error, and if you wondering how the other class or method, i will put event & state that seems related to the error:
state:
abstract class HospitalListState extends Equatable {
const HospitalListState();
#override
List<Object?> get props => [];
}
class HospitalListInitial extends HospitalListState {}
class HospitalListLoading extends HospitalListState {}
class HospitalListLoaded extends HospitalListState {
final List<HospitalListModel> hospitalListModel;
const HospitalListLoaded(this.hospitalListModel);
}
class HospitalListError extends HospitalListState {
final String? message;
const HospitalListError(this.message);
}
event:
abstract class HospitalListEvent extends Equatable {
const HospitalListEvent();
#override
List<Object> get props => [];
}
class GetCovidList extends HospitalListEvent {}
i made this code with flutter_bloc and if you want to know more details just let me know, and if you know what's wrong with my code, just type it on the answer, i appreciate every answers and knowledge that you share with me
You have missed ')' before using toList method you have close the map method.
hospitalList = mData.map<HospitalListModel>((e) => hospitalListModelFromJson(e))
.toList();

Flutter display Object entries

So I'm new to flutter and I simply want to display an Object that I receive from a server.
The Object looks something like this. So normally i would do something like Global.mEnergy.value
{
"Global":{
"mEnergy":{
"value":"-0",
"name":"WZ Wärmemenge",
"id":730,
"unit":"kWh",
"type":"value"
},
"mPower":{
"value":"-0.0",
"name":"WZ Leistung",
"id":732,
"unit":"kW",
"type":"value"
},
"xRelease":{
"value":"34",
"name":"Releaseinfo",
"id":727,
"unit":"",
"type":"value"
},
"xVersion":{
"value":"12.00",
"name":"Version Software",
"id":711,
"unit":"",
"type":"value"
},
"name":"Test"
},
"HW1":{
"rState_HW1":{
"value":"10",
"name":"State",
"id":222,
"unit":"",
"type":"value"
},
"pSetTemp_HW1":{
...
},
"rTopTemp_HW1":{
...
},
"pMinTemp_HW1":{
...
},
"pHWChrgTime1Begin_HW1":{
...
}
}
}
But I have really no idea how to start. I know i have to create a class like that
class Device {
final Object hw1;
final Object hw2;
final Object circuit1;
final Object circuit2;
final Object circuit3;
final Object circuit4;
final Object global;
const Device(
{required this.hw1,
required this.hw2,
required this.circuit1,
required this.circuit2,
required this.circuit3,
required this.circuit4,
required this.global});
factory Device.fromJson(Map<String, dynamic> json) {
return Device(
hw1: json['HW1'] as Object,
hw2: json['HW2'] as Object,
circuit1: json['1'] as Object,
circuit2: json['2'] as Object,
circuit3: json['3'] as Object,
circuit4: json['4'] as Object,
global: json['Global'] as Object,
);
}
}
Is there no easy way how I can access the object like this?
Text(snapshot.data!.global.mEnergy.value)
Most often, my strategy is to create classes that mimic the data structure for an API. That gives me the type-safe approach to getting and manipulating the data I need to.
Taking your data set, I have come up with some classes. The first is CommonProperties. Objects such as "mEnergy" in "global" and "rState_HW1" in "HW1" are composed of these properties.
class CommonProperties {
double? value;
String? name;
int? id;
String? unit;
String? type;
CommonProperties({
this.value,
this.name,
this.id,
this.unit,
this.type
});
factory CommonProperties.fromJson(dynamic data) {
data = data ?? {};
return CommonProperties(
value: data["value"],
name: data["name"],
id: data["id"],
unit: data["unit"],
type: data["type"]
);
}
Map<String, dynamic> toJson() {
return {
"value": value,
"name": name,
"id": id,
"unit": unit,
"type": type
};
}
}
Now you have the 2 upper-tier objects called "Global" and "HW1". These are composed of CommonProperties objects.
class Global {
CommonProperties? mEnergy;
CommonProperties? mPower;
CommonProperties? xRelease;
CommonProperties? xVersion;
String? name;
Global({
this.mEnergy,
this.mPower,
this.xRelease,
this.xVersion,
this.name
});
factory Global.fromJson(dynamic data) {
data = data ?? {};
return Global(
mEnergy: CommonProperties.fromJson(data["mEnergy"]),
mPower: CommonProperties.fromJson(data["mPower"]),
xRelease: CommonProperties.fromJson(data["xRelease"]),
xVersion: CommonProperties.fromJson(data["xVersion"]),
name: data["name"]
);
}
Map<String, dynamic> toJson() {
return {
"mEnergy": mEnergy!.toJson(),
"mPower": mPower!.toJson(),
"xRelease": xRelease!.toJson(),
"xVersion": xVersion!.toJson(),
"name": name
};
}
}
class HW1 {
CommonProperties? rState_HW1;
CommonProperties? pSetTemp_HW1;
CommonProperties? pTopTemp_HW1;
CommonProperties? rTopTemp_HW1;
CommonProperties? pMinTemp_HW1;
CommonProperties? pHWChrgTime1Begin_HW1;
HW1({
this.rState_HW1,
this.pSetTemp_HW1,
this.pTopTemp_HW1,
this.rTopTemp_HW1,
this.pMinTemp_HW1,
this.pHWChrgTime1Begin_HW1,
});
factory HW1.fromJson(dynamic data) {
data = data ?? {};
return HW1(
rState_HW1: CommonProperties.fromJson(data["rState_HW1"]),
pSetTemp_HW1: CommonProperties.fromJson(data["pSetTemp_HW1"]),
pTopTemp_HW1: CommonProperties.fromJson(data["pTopTemp_HW1"]),
rTopTemp_HW1: CommonProperties.fromJson(data["rTopTemp_HW1"]),
pMinTemp_HW1: CommonProperties.fromJson(data["pMinTemp_HW1"]),
pHWChrgTime1Begin_HW1: CommonProperties.fromJson(data["pHWChrgTime1Begin_HW1"]),
);
}
Map<String, dynamic> toJson() {
return {
"rState_HW1": rState_HW1!.toJson(),
"pSetTemp_HW1": pSetTemp_HW1!.toJson(),
"pTopTemp_HW1": pTopTemp_HW1!.toJson(),
"rTopTemp_HW1": rTopTemp_HW1!.toJson(),
"pMinTemp_HW1": pMinTemp_HW1!.toJson(),
"pHWChrgTime1Begin_HW1": pHWChrgTime1Begin_HW1!.toJson(),
};
}
}
Finally, I put it all together to build a class that represents the entire DataSet.
class DataSet {
Global? global;
HW1? hw1;
DataSet({
this.global,
this.hw1
});
factory DataSet.fromJson(dynamic data) {
data = data ?? {};
return DataSet(
global: Global.fromJson(data["global"]),
hw1: HW1.fromJson(data["HW1"])
);
}
Map<String, dynamic> toJson() {
return {
"global": global!.toJson(),
"hw1": hw1!.toJson(),
};
}
}
Notice that each class has a constructor for fromJson(data) and a method for toJson(). This is helpful to easily go to and from JSON data for interacting with APIs and such.
Now that I have everthing put together, I can pass the parsed JSON object from an API call into the DataSet.fromJson(data) constructor and I will have a type-safe object to work with all the data within that data set.
var parsedData = json.decode(httpResponse.body);
DataSet dataSet = DataSet.fromJson(parsedData);
print(dataSet.global.mEnergy.value);
print(dataSet.hw1.rState_HW1.value);

Make model class into List

I'm trying to have 2 data responses for 2 api endpoints. 1 is a single response, and the other is an array of a single response.
When trying to create the List/array version, I get errors. What's the proper way to make the following model class into a List as well?
class SingleDataResponse {
final String id;
final String title;
SingleDataResponse({
this.id,
this.title
});
factory SingleDataResponse.fromJson(Map<String, dynamic> json) {
return SingleDataResponse(
id: json['id'],
title: json['title']
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['title'] = this.title;
return data;
}
}
Here's what I'm expecting to get in the List Model:
[{_id: "5f210afa8215ff24307c6c53", title: "Cool Title"}]
just check out the example that I have created does this answer your question let me know.
This is the single object json
{
"_id": "5f210afa8215ff24307c6c53",
"title": "Cool Title"
}
This is the list of object:
[
{
"_id": "5f210afa8215ff24307c6c53",
"title": "Cool Title"
}
]
And this is the model class for the it I have taken the json locally.
// To parse this JSON data, do
import 'dart:convert';
// this is for single object
// final dataModel = singledataModelFromJson(jsonString);
DataModel singledataModelFromJson(String str) =>
DataModel.fromJson(json.decode(str));
String singledataModelToJson(DataModel data) => json.encode(data.toJson());
// this is for list of objects.
// final dataModel = dataModelFromJson(jsonString);
List<DataModel> dataModelFromJson(String str) =>
List<DataModel>.from(json.decode(str).map((x) => DataModel.fromJson(x)));
String dataModelToJson(List<DataModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class DataModel {
DataModel({
this.id,
this.title,
});
String id;
String title;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
id: json["_id"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"title": title,
};
}
This is the logic in main:
import 'package:flutter/material.dart';
import 'package:json_parsing_example/models.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: HomePage());
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double value;
#override
void initState() {
super.initState();
getdata();
}
getdata() async {
String data =
await DefaultAssetBundle.of(context).loadString("json/parse.json");
final singledataModel = singledataModelFromJson(data);
print('single model');
print(singledataModel.id);
print(singledataModel.title);
String listdata =
await DefaultAssetBundle.of(context).loadString("json/parse2.json");
List<DataModel> dataModel = dataModelFromJson(listdata);
print(dataModel.length);
print(dataModel[0].title);
}
#override
Widget build(BuildContext context) {
return Scaffold(body: Text(''));
}
}
Just check it and let me know if this is what you want.

How create a interface (class) in Dart for an nested Map

In my Flutter app I receive notifications with a custom payload, like:
{ notification:
{
title: Test,
body: AAAA
},
data:
{
productId: Axe,
page: Products,
click_action: FLUTTER_NOTIFICATION_CLICK
}
}
Everything works well. I also can handle the payload of the notification by access it through:
message['data']['page']
But I rather would like to use an Interface/Class to name the data by key, for example:
message.data.page and message.data.productId
So I tried:
class NotificationMessage {
Map notification;
Map data;
NotificationMessage(this.notification, this.data);
}
...
NotificationMessage _message = message; // Assigning the payload to the final
...
This where I get stuck: here I got the error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'NotificationMessage'.
My class isn't finished yet, but how to continue?
I' aware of json_serializable, but before any tooling, I would like to understand it fully.
First, you need to build the two models for notification and data as follows
class DataMessage {
final String productId;
final String page;
final String click_action;
DataMessage(this.productId, this.page, this.click_action);
factory DataMessage.fromJson(Map<dynamic, dynamic> json) {
return DataMessage(
json['productId'] as String,
json['page'] as String,
json['click_action'] as String,
);
}
}
class NotificationMessage {
final String title;
final String body;
NotificationMessage(this.title, this.body);
factory NotificationMessage.fromJson(Map<dynamic, dynamic> json) {
return NotificationMessage(
json['title'] as String,
json['body'] as String,
);
}
}
The factory method convert map types into model classes.
Then you have to build a model for the response message as follows
class Message {
final NotificationMessage notification;
final DataMessage data;
Message(this.notification, this.data);
factory Message.fromJson(Map<dynamic, dynamic> json) {
final Map<dynamic, dynamic> mapNotification = json['notification'];
final Map<dynamic, dynamic> mapData = json['data'];
final dataModel = DataMessage.fromJson(mapData);
final notificationModel = NotificationMessage.fromJson(mapNotification);
return Message(
notificationModel as NotificationMessage,
dataModel as DataMessage,
);
}
}
Note that the factory method allows you to convert the maps for each model to a class model
So you can define your response as a class
Map<dynamic, dynamic> messageResponse = {
'notification': {'title': 'Test', 'body': 'AAAA'},
'data': {
'productId': 'Axe',
'page': 'Products',
'click_action': 'FLUTTER_NOTIFICATION_CLICK'
}
};
final Message message = Message.fromJson(messageResponse);
print(message.data.productId);
print(message.data.page);
print(message.data.click_action);
print(message.notification.title);
print(message.notification.body);
Hope that can help you
Instance of the json object. this way you can use a map for any instance without modifying the class
{ "notification":
{
"title": "Test",
"body": "AAAA"
},
"data":
{
"productId": "Axe",
"page": "Products",
"click_action": "FLUTTER_NOTIFICATION_CLICK"
}
}
Class looks like;
class NotificationMessage {
NotificationMessage({
this.notification,
this.data,
});
final Notification notification;
final Data data;
factory NotificationMessage.fromJson(Map<String, dynamic> json) => NotificationMessage(
notification: Notification.fromJson(json["notification"]),
data: Data.fromJson(json["data"]),
);
Map<String, dynamic> toJson() => {
"notification": notification.toJson(),
"data": data.toJson(),
};
}
class Data {
Data({
this.productId,
this.page,
this.clickAction,
});
final String productId;
final String page;
final String clickAction;
factory Data.fromJson(Map<String, dynamic> json) => Data(
productId: json["productId"],
page: json["page"],
clickAction: json["click_action"],
);
Map<String, dynamic> toJson() => {
"productId": productId,
"page": page,
"click_action": clickAction,
};
}
class Notification {
Notification({
this.title,
this.body,
});
final String title;
final String body;
factory Notification.fromJson(Map<String, dynamic> json) => Notification(
title: json["title"],
body: json["body"],
);
Map<String, dynamic> toJson() => {
"title": title,
"body": body,
};
}
A function to build as
Future<NotificationMessage> getNotf() {
var parsedJson = json.decode(//your received object);
return NotificationMessage.fromJson(parsedJson);
}
Now you can receive this in a builder such as
_futureNotifications =Future<NotificationMessage>
_futureNotifications = getNotf(); //this is a function and can be used after a gesture or initState
FutureBuilder<NotificationMessage>(
future: _futureNotifications,
builder: (context, snapshot) {
}

An exception was thrown: NoSuchMethodError: The getter 'the0' was called on null

I'm trying to get data from API using Rest Service..
But I got an error saying that the getter was called on null, after doing some research, I found something, like the UI which the data I want to display was executed first than the getData function, it makes the system read the variable as null and the error occurs. Can anybody help me with this case..
Here this is a bit of my codes,
class PickUp extends StatefulWidget {
var created_name, wmsorders_id, id;
PickUp(
{Key key,
#required this.created_name,
#required this.wmsorders_id,
#required this.id})
: super(key: key);
#override
_PickUpState createState() => _PickUpState();
}
class _PickUpState extends State<PickUp> {
DetailModel detailModel;
String sender = "";
Future<String> getDetail() async {
print("id : " + widget.id);
var data = "id=" + widget.id + "";
var response_detail = await RestService()
.restRequestServiceGet(SystemParam.URL_DETAIL_UPCOMING, data);
print("response_detail : " + response_detail.body.toString());
setState(() {
detailModel = DetailModel.fromJson(jsonDecode(response_detail.body));
});
return "Success!";
}
#override
void initState() {
getDetail();
}
Widget build(BuildContext context) {
// NULL CHECKING
if (detailModel != null) {
print("sender =" +detailModel.the0.picName);
} else {
print("sender = null");
}
// I want to get picName from detail Model and using it in UI, but I got Error here
sender = detailModel.the0.picName';
print("sender = " +'$sender');
}
Here is the detailModel
// To parse this JSON data, do
//
// final detailModel = detailModelFromJson(jsonString);
import 'dart:convert';
DetailModel detailModelFromJson(String str) => DetailModel.fromJson(json.decode(str));
String detailModelToJson(DetailModel data) => json.encode(data.toJson());
class DetailModel {
The0 the0;
The0 the1;
Records records;
DetailModel({
this.the0,
this.the1,
this.records,
});
factory DetailModel.fromJson(Map<String, dynamic> json) => DetailModel(
the0: The0.fromJson(json["0"]),
the1: The0.fromJson(json["1"]),
records: Records.fromJson(json["records"]),
);
Map<String, dynamic> toJson() => {
"0": the0.toJson(),
"1": the1.toJson(),
"records": records.toJson(),
};
}
class Records {
int status;
String message;
Records({
this.status,
this.message,
});
factory Records.fromJson(Map<String, dynamic> json) => Records(
status: json["status"],
message: json["message"],
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
};
}
class The0 {
String id;
String sku;
int sak;
String qty;
String shipstatId;
String picName;
String picTelp;
String orderMultipleId;
String orderdetId;
String coordinatorId;
The0({
this.id,
this.sku,
this.sak,
this.qty,
this.shipstatId,
this.picName,
this.picTelp,
this.orderMultipleId,
this.orderdetId,
this.coordinatorId,
});
factory The0.fromJson(Map<String, dynamic> json) => The0(
id: json["id"],
sku: json["sku"],
sak: json["sak"],
qty: json["qty"],
shipstatId: json["shipstat_id"],
picName: json["pic_name"],
picTelp: json["pic_telp"],
orderMultipleId: json["order_multiple_id"],
orderdetId: json["orderdet_id"],
coordinatorId: json["coordinator_id"],
);
Map<String, dynamic> toJson() => {
"id": id,
"sku": sku,
"sak": sak,
"qty": qty,
"shipstat_id": shipstatId,
"pic_name": picName,
"pic_telp": picTelp,
"order_multiple_id": orderMultipleId,
"orderdet_id": orderdetId,
"coordinator_id": coordinatorId,
};
}
And here is the Error,
You need to use FutureBuilder in build method and wait until response.
Remove setstate and Modify the code as below.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Test',
style: TextStyle(
color: Colors.white,
),
),
),
body: FutureBuilder<DetailModel>(
future: getDetail(),
builder: (context, snapshot) {
if (snapshot.hasData) {
print("Here you can get data "+snapshot.data.toString());
} else {
print("Waiting mode");
return Container(
color: Colors.blue,
);
}
},
),
);
}
}