I cannot display my response in text widgets in flutter - flutter

I have used post method for user login which is successfully done and it returns responses in list which I need to display in text widget in some other class, but when I try to display it in text widget using Future builder it throws exception in my emulator but nothing shows in my console.
This is my APIService class, it works fine when I post details but when i try to display the response in text widget, it shows exception from this class, at the bottom of this code there is " throw Exception('Failed');" it shows this exception only when I try to display the response in text widgets.
class APIService {
Future<DoctorResponseLoginModels> register(
DoctorRequestLoginModels doctorLoginRequestModels) async {
String url = "http://202.51.75.142:9028/api/PatientMaster/PostPatientLogin";
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
var globalToken = sharedPreferences.getString("token");
print("$globalToken");
http.Response response = await http.post(Uri.parse(url),
headers: {
"Content-Type": "application/json",
'Accept': 'application/json',
'Authorization': 'Bearer $globalToken',
},
body: jsonEncode(doctorLoginRequestModels));
var responseJson = json.decode(response.body.toString());
DoctorResponseLoginModels responseModel =
DoctorResponseLoginModels.fromJson(responseJson);
print("This is ${response.body}");
if (response.statusCode == 200) {
sharedPreferences.setInt('code', response.statusCode);
var StatusCode = sharedPreferences.getInt('code');
print("This contains : $StatusCode");
return DoctorResponseLoginModels.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed');
}
}
}
This is My DoctorRequestLoginModels class which I send to server.
DoctorRequestLoginModels doctorRequestLoginModelsFromJson(String str) =>
DoctorRequestLoginModels.fromJson(json.decode(str));
String doctorRequestLoginModelsToJson(DoctorRequestLoginModels data) =>
json.encode(data.toJson());
class DoctorRequestLoginModels {
DoctorRequestLoginModels({
required this.code,
required this.username,
required this.password,
});
String code;
String username;
String password;
factory DoctorRequestLoginModels.fromJson(Map<String, dynamic> json) =>
DoctorRequestLoginModels(
code: json["code"],
username: json["username"],
password: json["password"],
);
Map<String, dynamic> toJson() => {
"code": code,
"username": username,
"password": password,
};
}
This is my DoctorRespinseModels class which I need to display in text widgets.
DoctorResponseLoginModels doctorResponseLoginModelsFromJson(String str) =>
DoctorResponseLoginModels.fromJson(json.decode(str));
String doctorResponseLoginModelsToJson(DoctorResponseLoginModels data) =>
json.encode(data.toJson());
class DoctorResponseLoginModels {
DoctorResponseLoginModels({
this.doctorId,
this.nmCno,
this.doctorName,
this.contactNo,
this.username,
this.emailId,
this.strEmail,
this.id,
this.intMobile,
this.gender,
this.currentAddress,
this.depId,
this.entryDate,
this.password,
this.code,
this.isActive,
this.hospitalName,
this.department,
this.deviceId,
this.profile,
this.token,
this.role,
});
int? doctorId;
String? nmCno;
String? doctorName;
String? contactNo;
dynamic? username;
String? emailId;
String? strEmail;
int? id;
String? intMobile;
dynamic? gender;
String? currentAddress;
int? depId;
String? entryDate;
dynamic? password;
dynamic? code;
bool? isActive;
dynamic? hospitalName;
dynamic? department;
dynamic? deviceId;
String? profile;
String? token;
String? role;
factory DoctorResponseLoginModels.fromJson(Map<String, dynamic> json) =>
DoctorResponseLoginModels(
doctorId: json["doctorID"],
nmCno: json["nmCno"],
doctorName: json["doctorName"],
contactNo: json["contactNo"],
username: json["username"],
emailId: json["emailID"],
strEmail: json["strEmail"],
id: json["id"],
intMobile: json["intMobile"],
gender: json["gender"],
currentAddress: json["currentAddress"],
depId: json["depId"],
entryDate: json["entryDate"],
password: json["password"],
code: json["code"],
isActive: json["isActive"],
hospitalName: json["hospitalName"],
department: json["department"],
deviceId: json["deviceId"],
profile: json["profile"],
token: json["token"],
role: json["role"],
);
Map<String, dynamic> toJson() => {
"doctorID": doctorId,
"nmCno": nmCno,
"doctorName": doctorName,
"contactNo": contactNo,
"username": username,
"emailID": emailId,
"strEmail": strEmail,
"id": id,
"intMobile": intMobile,
"gender": gender,
"currentAddress": currentAddress,
"depId": depId,
"entryDate": entryDate,
"password": password,
"code": code,
"isActive": isActive,
"hospitalName": hospitalName,
"department": department,
"deviceId": deviceId,
"profile": profile,
"token": token,
"role": role,
};
}
And this is where I need it to be displayed, where I have used FutureBuilder and I this I made a mistake here but not sure where exactly.
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: const Color.fromRGBO(249, 249, 249, 10),
body: Column(
children: [
Expanded(
child: Container(
height: 150.0,
width: 150.0,
color: Colors.grey.shade100,
child: FutureBuilder<DoctorResponseLoginModels>(
future: APIService().register(DoctorRequestLoginModels(
code: "code", username: "username", password: "password")),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
DoctorResponseLoginModels data = snapshot.data!;
return Column(
children: [
Text(data.doctorName!),
],
);
}
}
},
),
)),
],
));
}

Related

I got an error when trying to get data from the API error type 'null' is not a subtype of type 'string'

hello permission to ask I'm trying to get the API to then display and the response is 200 ok. but when I try to display it on the screen the following error occurs
this is a function to get data from API
Future<Datum> getPaketKuliah() async {
String url = Constant.baseURL;
String token = await UtilSharedPreferences.getToken();
final response = await http.get(
Uri.parse(
'$url/auth/mhs_siakad/perwalian/get_paket',
),
headers: {
'Authorization': 'Bearer $token',
},
);
print(response.statusCode);
print(response.body);
if (response.statusCode == 200) {
return Datum.fromJson(jsonDecode(response.body));
} else {
throw Exception();
}
}
and I want to display it on the page using FutureBuilder
Container(
child: FutureBuilder<Datum>(
future: AuthProvider().getPaketKuliah(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.kelas);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
),
),
and lastly this is the model class I want to take to display on the
page
// To parse this JSON data, do
//
// final getPaket = getPaketFromJson(jsonString);
import 'dart:convert';
GetPaket getPaketFromJson(String str) => GetPaket.fromJson(json.decode(str));
String getPaketToJson(GetPaket data) => json.encode(data.toJson());
class GetPaket {
GetPaket({
required this.status,
required this.code,
required this.data,
});
String status;
String code;
Map<String, Datum> data;
factory GetPaket.fromJson(Map<String, dynamic> json) => GetPaket(
status: json["status"],
code: json["code"],
data: Map.from(json["data"])
.map((k, v) => MapEntry<String, Datum>(k, Datum.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"status": status,
"code": code,
"data": Map.from(data)
.map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class Datum {
Datum({
this.id,
this.idDosen,
this.idMk,
required this.nidn,
this.dosen,
this.idKelasKuliah,
this.kelasKuliah,
this.prodi,
this.kelas,
this.semester,
this.kelompokKelas,
required this.kode,
this.sks,
this.jumlahKelas,
this.matakuliah,
this.smt,
this.bobotSks,
this.rencanaPertemuan,
this.jenisEvaluasi,
required this.createdAt,
required this.updatedAt,
this.createdBy,
this.updatedBy,
});
String? id;
String? idDosen;
String? idMk;
dynamic nidn;
String? dosen;
String? idKelasKuliah;
String? kelasKuliah;
String? prodi;
String? kelas;
String? semester;
String? kelompokKelas;
dynamic kode;
int? sks;
int? jumlahKelas;
String? matakuliah;
String? smt;
int? bobotSks;
int? rencanaPertemuan;
String? jenisEvaluasi;
DateTime createdAt;
DateTime updatedAt;
String? createdBy;
String? updatedBy;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
idDosen: json["id_dosen"],
idMk: json["id_mk"],
nidn: json["nidn"],
dosen: json["dosen"],
idKelasKuliah: json["id_kelas_kuliah"],
kelasKuliah: json["kelas_kuliah"],
prodi: json["prodi"],
kelas: json["kelas"],
semester: json["semester"],
kelompokKelas: json["kelompok_kelas"],
kode: json["kode"],
sks: json["sks"],
jumlahKelas: json["jumlah_kelas"],
matakuliah: json["matakuliah"],
smt: json["smt"],
bobotSks: json["bobot_sks"],
rencanaPertemuan: json["rencana_pertemuan"],
jenisEvaluasi: json["jenis_evaluasi"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
createdBy: json["created_by"],
updatedBy: json["updated_by"],
);
Map<String, dynamic> toJson() => {
"id": id,
"id_dosen": idDosen,
"id_mk": idMk,
"nidn": nidn,
"dosen": dosen,
"id_kelas_kuliah": idKelasKuliah,
"kelas_kuliah": kelasKuliah,
"prodi": prodi,
"kelas": kelas,
"semester": semester,
"kelompok_kelas": kelompokKelas,
"kode": kode,
"sks": sks,
"jumlah_kelas": jumlahKelas,
"matakuliah": matakuliah,
"smt": smt,
"bobot_sks": bobotSks,
"rencana_pertemuan": rencanaPertemuan,
"jenis_evaluasi": jenisEvaluasi,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"created_by": createdBy,
"updated_by": updatedBy,
};
}
and this is the json response
I highly recommend using library like json_serilizable to generate factory fromJson
factory Paket.romJson(Map<String, dynamic> json) => Paket(
status: json['status'] as String,
code: json['code'] as String,
data: (json['data'] as Map<String, dynamic>).map(
(k, e) => MapEntry(k, Datum.fromJson(e as Map<String, dynamic>)),
),
);
As provided api response corresponds to GetPaket class not Datum class you need to change getPaketKuliah method to
Future<Datum> getPaketKuliah() async {
String url = Constant.baseURL;
String token = await UtilSharedPreferences.getToken();
final response = await http.get(
Uri.parse(
'$url/auth/mhs_siakad/perwalian/get_paket',
),
headers: {
'Authorization': 'Bearer $token',
},
);
print(response.statusCode);
print(response.body);
if (response.statusCode == 200) {
// --return Datum.fromJson(jsonDecode(response.body));
final paket = GetPaket.fromJson(jsonDecode(response.body));
// -- return Datum.fromJson(paket.data.entries.first.value);
return paket.data.entries.first.value;
} else {
throw Exception();
}
}

How do i display api responses in text widgets in flutter?

In the following image, I am using the post method to send the data, which is successfully done and when the server returns the response which is can be seen in the user's console, now how do I display those responses in text widgets in another class?
This is my Api class where I use post method.
class APIService {
Future<DoctorResponseLoginModels> register(
DoctorRequestLoginModels doctorLoginRequestModels) async {
String url = "http://202.51.75.142:9028/api/PatientMaster/PostPatientLogin";
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
var globalToken = sharedPreferences.getString("token");
print("$globalToken");
http.Response response = await http.post(Uri.parse(url),
headers: {
"Content-Type": "application/json",
'Accept': 'application/json',
'Authorization': 'Bearer $globalToken',
},
body: jsonEncode(doctorLoginRequestModels));
var responseJson = json.decode(response.body.toString());
DoctorResponseLoginModels responseModel =
DoctorResponseLoginModels.fromJson(responseJson);
print("This is ${response.body}");
if (response.statusCode == 200) {
sharedPreferences.setInt('code', response.statusCode);
var StatusCode = sharedPreferences.getInt('code');
print("This contains : $StatusCode");
print(response.statusCode);
return DoctorResponseLoginModels.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed');
}
}
}
This is my Request Class model which I sent to server
DoctorRequestLoginModels doctorRequestLoginModelsFromJson(String str) =>
DoctorRequestLoginModels.fromJson(json.decode(str));
String doctorRequestLoginModelsToJson(DoctorRequestLoginModels data) =>
json.encode(data.toJson());
class DoctorRequestLoginModels {
DoctorRequestLoginModels({
required this.code,
required this.username,
required this.password,
});
String code;
String username;
String password;
factory DoctorRequestLoginModels.fromJson(Map<String, dynamic> json) =>
DoctorRequestLoginModels(
code: json["code"],
username: json["username"],
password: json["password"],
);
Map<String, dynamic> toJson() => {
"code": code,
"username": username,
"password": password,
};
}
This is my Response Models class which I need to display in text
DoctorResponseLoginModels doctorResponseLoginModelsFromJson(String str) =>
DoctorResponseLoginModels.fromJson(json.decode(str));
String doctorResponseLoginModelsToJson(DoctorResponseLoginModels data) =>
json.encode(data.toJson());
class DoctorResponseLoginModels {
DoctorResponseLoginModels({
this.doctorId,
this.nmCno,
this.doctorName,
this.contactNo,
this.username,
this.emailId,
this.strEmail,
this.id,
this.intMobile,
this.gender,
this.currentAddress,
this.depId,
this.entryDate,
this.password,
this.code,
this.isActive,
this.hospitalName,
this.department,
this.deviceId,
this.profile,
this.token,
this.role,
});
int? doctorId;
String? nmCno;
String? doctorName;
String? contactNo;
dynamic? username;
String? emailId;
String? strEmail;
int? id;
String? intMobile;
dynamic? gender;
String? currentAddress;
int? depId;
String? entryDate;
dynamic? password;
dynamic? code;
bool? isActive;
dynamic? hospitalName;
dynamic? department;
dynamic? deviceId;
String? profile;
String? token;
String? role;
factory DoctorResponseLoginModels.fromJson(Map<String, dynamic> json) =>
DoctorResponseLoginModels(
doctorId: json["doctorID"],
nmCno: json["nmCno"],
doctorName: json["doctorName"],
contactNo: json["contactNo"],
username: json["username"],
emailId: json["emailID"],
strEmail: json["strEmail"],
id: json["id"],
intMobile: json["intMobile"],
gender: json["gender"],
currentAddress: json["currentAddress"],
depId: json["depId"],
entryDate: json["entryDate"],
password: json["password"],
code: json["code"],
isActive: json["isActive"],
hospitalName: json["hospitalName"],
department: json["department"],
deviceId: json["deviceId"],
profile: json["profile"],
token: json["token"],
role: json["role"],
);
Map<String, dynamic> toJson() => {
"doctorID": doctorId,
"nmCno": nmCno,
"doctorName": doctorName,
"contactNo": contactNo,
"username": username,
"emailID": emailId,
"strEmail": strEmail,
"id": id,
"intMobile": intMobile,
"gender": gender,
"currentAddress": currentAddress,
"depId": depId,
"entryDate": entryDate,
"password": password,
"code": code,
"isActive": isActive,
"hospitalName": hospitalName,
"department": department,
"deviceId": deviceId,
"profile": profile,
"token": token,
"role": role,
};
}
This is where I am using Future Builder to display in Text
return Scaffold(
backgroundColor: const Color.fromRGBO(249, 249, 249, 10),
body: Column(
children: [
Expanded(
child: Container(
height: 150.0,
width: 150.0,
color: Colors.grey.shade100,
child: FutureBuilder<DoctorResponseLoginModels>(
future: APIService().register(DoctorRequestLoginModels(
code: "code", username: "username", password: "password")),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
DoctorResponseLoginModels data = snapshot.data!;
return Column(
children: [
Text(data.doctorName!),
],
);
}
}
},
),
)),
],
));
And this is the image of response I get in my console after I use post method and this is the response which I need to display in my text widgets
The correct approach would be to put the API-Class to a Provider.
Access the Instance whenever you need.
You can use FutureBuilder like this:
FutureBuilder<DoctorResponseLoginModels>(
future: APIService().register(...),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
DoctorResponseLoginModels data = snapshot.data!;
return Column(
children: [
Text(data.doctorName ?? ''),
Text(data.username?? ''),
],
);
}
}
},
),

Sending data with nested JSON

I have a two textfields; (body and user), which i want to parse their data to my json(nested). but the exception is being thrown instead
The snippet below is my JSON representation
{
"id": 27,
"user": {
"username": "admin"
},
"body": "Saturday morning",
"updated": "2022-07-30T06:48:53.009515Z",
"created": "2022-07-30T06:48:53.009515Z"
},
below is how i am sending the data
Future<Note> createNote(String body, String username) async {
final response = await http.post(
noteUrl,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, dynamic>{
'body': body,
'user': username,
}),
);
if (response.statusCode == 201) {
return Note.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to create note');
}
}
this is where i am calling the function to send the data
ElevatedButton(
onPressed: () {
createNote(_bodyController.text, _userController.text);
Navigator.popAndPushNamed(context, '/');
},
child: Text('submit'),
)
Below snippet is my model class(flutter)
import 'dart:convert';
List<Note> noteFromJson(String str) =>
List<Note>.from(json.decode(str).map((x) => Note.fromJson(x)));
String noteToJson(List<Note> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Note {
Note({
this.id,
required this.body,
this.updated,
this.created,
this.user,
});
int? id;
String body;
DateTime? updated;
DateTime? created;
User? user;
factory Note.fromJson(Map<String, dynamic> json) => Note(
id: json["id"],
body: json["body"] as String,
updated: DateTime.parse(json["updated"]),
created: DateTime.parse(json["created"]),
user: User.fromJson(json["user"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"body": body,
"updated": updated?.toIso8601String(),
"created": created?.toIso8601String(),
"user": user?.toJson()
};
}
List<User> userFromJson(String str) =>
List<User>.from(json.decode(str).map((x) => User.fromJson(x)));
String userToJson(List<User> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class User {
User({
this.id,
required this.username,
this.password,
this.email,
});
String? id;
String username;
String? password;
String? email;
factory User.fromJson(Map<String, dynamic> json) => User(
id: json["id"],
username: json["username"],
password: json["password"],
email: json["email"],
);
Map<String, dynamic> toJson() => {
"id": id,
"username": username,
"password": password,
"email": email,
};
}

How to integrate api using class model in flutter

I'm trying to Integrate the API using model. Let say I have a book screen, so I'm trying to get its API data using model. my model looks like this.
class Book {
final int id;
final String phone;
final String name;
final String relation;
final String updated_at;
final String created_at;
final int userId;
Book(
{required this.id,
required this.name,
required this.phone,
required this.relation,
required this.created_at,
// required this.image,
required this.updated_at,
required this.userId,
});
factory Book.fromJson(Map<String, dynamic> json) => Book(
id: json['user_id'],
name: json['contact_person'],
relation: json['relation'],
phone: json['phone'],
updated_at: json['updated_at'],
created_at: json['created_at'],
userId: json['id']
);
Map<String, dynamic> toJson() => {
'user_id': userId,
'contact_person': phone,
'relation': relation,
'name': name,
'created_at':created_at,
'updated_at':updated_at,
'id':id,
};
}
calling this api like this
Future<List<Book>> getBook() async {
List<Book> _bookList =[];
Map<String, String> headers = {
"Content-type": "application/json",
'Authorization': 'Bearer $token',
};
var url = Uri.parse(ApiPath.getAllEmergenceyContactUrl);
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
Map<String, dynamic> map = json.decode(response.body);
List<dynamic> data = map["user"];
if(data.length>0){
for(int i=0;i<data.length;i++){
if(data[i]!=null){
Map<String,dynamic> map=data[i];
_bookList.add(Book.fromJson(map));
debugPrint('Id-------${map['contact_person']}'); //this print the correct data
}
}
}
print(_bookList);
return _bookList;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
print(_bookList); this give me this output
[Instance of 'Book', Instance of 'Book']
and calling in User Interface like this
List<Book> books = [];
getAllEmergenceyContacts()async{
var books = await services.getBook();
}
i can't able to get the the when using the books in listview builder, please help me out.
my json data look like this
{
"status": 1,
"message": "your emergency contacts",
"user": [
{
"id": 10,
"user_id": 49,
"contact_person": "ABC",
"relation": "DSVKJDSB",
"phone": "sdfsdf",
"image": "emergency/1735686398652391.png",
"created_at": "2022-06-15T07:52:19.000000Z",
"updated_at": "2022-06-15T07:52:19.000000Z"
},
]}
and i want user array data from it.
I optimized your code and fix your problem. You can try it and tell me if have any problem
Model
import 'dart:convert';
Book bookFromJson(String str) => Book.fromJson(json.decode(str));
String bookToJson(Book data) => json.encode(data.toJson());
class Book {
Book({
this.status,
this.message,
this.user,
});
int status;
String message;
List<User> user;
factory Book.fromJson(Map<String, dynamic> json) => Book(
status: json["status"],
message: json["message"],
user: List<User>.from(json["user"].map((x) => User.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"user": List<dynamic>.from(user.map((x) => x.toJson())),
};
}
class User {
User({
this.id,
this.userId,
this.contactPerson,
this.relation,
this.phone,
this.image,
this.createdAt,
this.updatedAt,
});
int id;
int userId;
String contactPerson;
String relation;
String phone;
String image;
DateTime createdAt;
DateTime updatedAt;
factory User.fromJson(Map<String, dynamic> json) => User(
id: json["id"],
userId: json["user_id"],
contactPerson: json["contact_person"],
relation: json["relation"],
phone: json["phone"],
image: json["image"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"user_id": userId,
"contact_person": contactPerson,
"relation": relation,
"phone": phone,
"image": image,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
Call API
Future getBook() async {
Map<String, String> headers = {
"Content-type": "application/json",
'Authorization': 'Bearer $token',
};
var url = Uri.parse(ApiPath.getAllEmergenceyContactUrl);
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
return bookFromJson(response.body).user;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
Calling in ui screen
List<Book> books = [];
getAllEmergenceyContacts()async{
books = await services.getBook();
setState((){});
}
Listview builder
ListView.builder(
itemCount: books.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(books[index].name),
);
},
),
print(_bookList); this gives you this output [Instance of 'Book', Instance of 'Book'] because you try to print every Book class instance
You declare List<Book> _bookList =[]; , where _bookList holds Book Class as a child.
At first, Fetch the books from API
List<Book> books = [];
getAllEmergenceyContacts()async{
var books = await services.getBook();
}
Then, you Should place all the books inside List view builder like the following way
ListView.builder(
itemCount: books.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(books[index].name),
);
},
),

flutter building listview with response from restapi

typical json response:
{"data":[{"id":1,"partnerTypeId":1,"active":true,"name":"Covin - AINO UG","shortname":"Covin","firstname":null,"lastname":null,"addressId":1,"phoneId":null,"countryId":"in","email":"support#covin.in","web":"www.covin.in","infos":{},"note":null,"createdAt":"2021-03-06 23:30:30","updatedAt":"2021-03-06 23:30:30","updatedBy":null},{"id":41,"partnerTypeId":100,"active":true,"name":"Tester IND","shortname":"T.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"email#tester","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:02","updatedAt":"2021-03-07 01:25:06","updatedBy":null},{"id":42,"partnerTypeId":100,"active":true,"name":"MIT Charl","shortname":"KITA Ch.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"kisa1#kol","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:42","updatedAt":"2021-03-07 01:25:08","updatedBy":null}]}
Generated podo class:
filename- partnerList.dart
// To parse this JSON data, do
//
// final partnerList = partnerListFromMap(jsonString);
import 'dart:convert';
PartnerList partnerListFromMap(String str) => PartnerList.fromMap(json.decode(str));
String partnerListToMap(PartnerList data) => json.encode(data.toMap());
class PartnerList {
PartnerList({
this.data,
});
List<Datum> data;
factory PartnerList.fromMap(Map<String, dynamic> json) => PartnerList(
data: List<Datum>.from(json["data"].map((x) => Datum.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"data": List<dynamic>.from(data.map((x) => x.toMap())),
};
}
class Datum {
Datum({
this.id,
this.partnerTypeId,
this.active,
this.name,
this.shortname,
this.firstname,
this.lastname,
this.addressId,
this.phoneId,
this.countryId,
this.email,
this.web,
this.infos,
this.note,
this.createdAt,
this.updatedAt,
this.updatedBy,
});
int id;
int partnerTypeId;
bool active;
String name;
String shortname;
dynamic firstname;
dynamic lastname;
int addressId;
dynamic phoneId;
String countryId;
String email;
String web;
Infos infos;
dynamic note;
DateTime createdAt;
DateTime updatedAt;
dynamic updatedBy;
factory Datum.fromMap(Map<String, dynamic> json) => Datum(
id: json["id"],
partnerTypeId: json["partnerTypeId"],
active: json["active"],
name: json["name"],
shortname: json["shortname"],
firstname: json["firstname"],
lastname: json["lastname"],
addressId: json["addressId"] == null ? null : json["addressId"],
phoneId: json["phoneId"],
countryId: json["countryId"],
email: json["email"],
web: json["web"] == null ? null : json["web"],
infos: Infos.fromMap(json["infos"]),
note: json["note"],
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
updatedBy: json["updatedBy"],
);
Map<String, dynamic> toMap() => {
"id": id,
"partnerTypeId": partnerTypeId,
"active": active,
"name": name,
"shortname": shortname,
"firstname": firstname,
"lastname": lastname,
"addressId": addressId == null ? null : addressId,
"phoneId": phoneId,
"countryId": countryId,
"email": email,
"web": web == null ? null : web,
"infos": infos.toMap(),
"note": note,
"createdAt": createdAt.toIso8601String(),
"updatedAt": updatedAt.toIso8601String(),
"updatedBy": updatedBy,
};
}
class Infos {
Infos();
factory Infos.fromMap(Map<String, dynamic> json) => Infos(
);
Map<String, dynamic> toMap() => {
};
}
related fetch class: file name - partner.api.dart
import 'partnerList.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
Future<List<PartnerList>> fetchPartner() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final userid = prefs.getString('user_id');
final token = prefs.getString('token');
Map<String, String> requestHeaders = {
'Accept': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $token',
};
final response = await http.get("https://api.covin.in/partners/",
headers: requestHeaders);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response.body);
return partnerListFromMap(response.body);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load PartnerList');
}
}
Now the first error I am getting:
A value of type 'PartnerList' can't be returned from the function 'fetchPartner' because it has a return type of 'Future<List<PartnerList>>'.dartreturn_of_invalid_type
how I can fix this?
update: I have modified the function partnerListfromMap like below:
List<PartnerList> partnerListFromMap(String str) => List<PartnerList>.from(json.decode(str));
String partnerListToMap(PartnerList data) => json.encode(data.toMap());
but I am getting another error now:
Exception has occurred. _TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>')
You can copy paste run full code below
Your json string is PartnerList not List<PartnerList>
You can use Future<PartnerList> and use return Future.value
code snippet
Future<PartnerList> fetchPartner() async {
...
return Future.value(partnerListFromMap(response.body));
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
PartnerList partnerListFromMap(String str) =>
PartnerList.fromMap(json.decode(str));
String partnerListToMap(PartnerList data) => json.encode(data.toMap());
class PartnerList {
PartnerList({
this.data,
});
List<Datum> data;
factory PartnerList.fromMap(Map<String, dynamic> json) => PartnerList(
data: List<Datum>.from(json["data"].map((x) => Datum.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"data": List<dynamic>.from(data.map((x) => x.toMap())),
};
}
class Datum {
Datum({
this.id,
this.partnerTypeId,
this.active,
this.name,
this.shortname,
this.firstname,
this.lastname,
this.addressId,
this.phoneId,
this.countryId,
this.email,
this.web,
this.infos,
this.note,
this.createdAt,
this.updatedAt,
this.updatedBy,
});
int id;
int partnerTypeId;
bool active;
String name;
String shortname;
dynamic firstname;
dynamic lastname;
int addressId;
dynamic phoneId;
String countryId;
String email;
String web;
Infos infos;
dynamic note;
DateTime createdAt;
DateTime updatedAt;
dynamic updatedBy;
factory Datum.fromMap(Map<String, dynamic> json) => Datum(
id: json["id"],
partnerTypeId: json["partnerTypeId"],
active: json["active"],
name: json["name"],
shortname: json["shortname"],
firstname: json["firstname"],
lastname: json["lastname"],
addressId: json["addressId"] == null ? null : json["addressId"],
phoneId: json["phoneId"],
countryId: json["countryId"],
email: json["email"],
web: json["web"] == null ? null : json["web"],
infos: Infos.fromMap(json["infos"]),
note: json["note"],
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
updatedBy: json["updatedBy"],
);
Map<String, dynamic> toMap() => {
"id": id,
"partnerTypeId": partnerTypeId,
"active": active,
"name": name,
"shortname": shortname,
"firstname": firstname,
"lastname": lastname,
"addressId": addressId == null ? null : addressId,
"phoneId": phoneId,
"countryId": countryId,
"email": email,
"web": web == null ? null : web,
"infos": infos.toMap(),
"note": note,
"createdAt": createdAt.toIso8601String(),
"updatedAt": updatedAt.toIso8601String(),
"updatedBy": updatedBy,
};
}
class Infos {
Infos();
factory Infos.fromMap(Map<String, dynamic> json) => Infos();
Map<String, dynamic> toMap() => {};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<PartnerList> _future;
Future<PartnerList> fetchPartner() async {
String jsonString = '''
{"data":[{"id":1,"partnerTypeId":1,"active":true,"name":"Covin - AINO UG","shortname":"Covin","firstname":null,"lastname":null,"addressId":1,"phoneId":null,"countryId":"in","email":"support#covin.in","web":"www.covin.in","infos":{},"note":null,"createdAt":"2021-03-06 23:30:30","updatedAt":"2021-03-06 23:30:30","updatedBy":null},{"id":41,"partnerTypeId":100,"active":true,"name":"Tester IND","shortname":"T.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"email#tester","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:02","updatedAt":"2021-03-07 01:25:06","updatedBy":null},{"id":42,"partnerTypeId":100,"active":true,"name":"MIT Charl","shortname":"KITA Ch.","firstname":null,"lastname":null,"addressId":null,"phoneId":null,"countryId":"IN","email":"kisa1#kol","web":null,"infos":{},"note":null,"createdAt":"2021-03-06 23:32:42","updatedAt":"2021-03-07 01:25:08","updatedBy":null}]}
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response.body);
return Future.value(partnerListFromMap(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load PartnerList');
}
}
#override
void initState() {
_future = fetchPartner();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<PartnerList> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data.data[index].id
.toString()),
Spacer(),
Text(
snapshot.data.data[index].name,
),
],
),
));
});
}
}
}));
}
}
Try this:
// this is correct. I think you generated this using app.quicktype.io ? Then it's correct.
PartnerList partnerListFromMap(String str) => PartnerList.fromMap(json.decode(str));
// you want the list of Datum.
Future<List<Datum>> fetchPartner() async {
// other codes here ...
return partnerListFromMap(response.body).data;
// other codes here ...
}