问题
Im trying to get an response from provider and fetching in a ui page but when i try to add an response to ui it shows an error
The getter 'data' was called on null. Receiver: null Tried calling: data
In this Line:
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: doctorList.data.length,
primary: true,
is this is correct approuch or need to change modal class or ui integration. im accessing data through doctorList.data.->datas data.
My response modal class.
import 'dart:convert';
Doctorlist doctorlistFromJson(String str) => Doctorlist.fromJson(json.decode(str));
String doctorlistToJson(Doctorlist data) => json.encode(data.toJson());
class Doctorlist {
Doctorlist({
this.status,
this.message,
this.data,
});
int status;
String message;
List<Datum> data;
factory Doctorlist.fromJson(Map<String, dynamic> json) => Doctorlist(
status: json["status"],
message: json["message"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.mobile,
this.userImage,
this.emrNumber,
this.hospital,
this.status,
this.doctorName,
this.docRole,
this.email,
this.gender,
this.address,
this.city,
this.state,
this.pincode,
this.clinicName,
this.appointmentDate,
this.favourite,
});
String id;
String mobile;
String userImage;
String emrNumber;
String hospital;
String status;
String doctorName;
String docRole;
String email;
String gender;
String address;
String city;
String state;
String pincode;
String clinicName;
DateTime appointmentDate;
String favourite;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
mobile: json["mobile"],
userImage: json["user_image"],
no: json["no"],
hospital: json["hospital"],
status: json["status"],
doctorName: json["doctor_name"],
docRole: json["doc_role"],
email: json["email"],
gender: json["gender"],
address: json["address"],
city: json["city"],
state: json["state"],
pincode: json["pincode"],
clinicName: json["clinic_name"],
appointmentDate: DateTime.parse(json["appointment_date"]),
favourite: json["favourite"],
);
Map<String, dynamic> toJson() => {
"id": id,
"mobile": mobile,
"user_image": userImage,
"emr_number": emrNumber,
"hospital": hospital,
"status": status,
"doctor_name": doctorName,
"doc_role": docRole,
"email": email,
"gender": gender,
"address": address,
"city": city,
"state": state,
"pincode": pincode,
"clinic_name": clinicName,
"appointment_date": "${appointmentDate.year.toString().padLeft(4, '0')}-${appointmentDate.month.toString().padLeft(2, '0')}-${appointmentDate.day.toString().padLeft(2, '0')}",
"favourite": favourite,
};
}
My Provider class:
class DoctorListProvider extends ChangeNotifier {
Doctorlist doctorList;
Future<Doctorlist> doctorlist() async {
try {
final response = await http.post(
(Commons.baseURL + "/list"),
headers: {
"Accept": "application/json",
"content-type": "application/json",
},body:{"id":5});
if (response.statusCode == 200) {
var responseJson = Commons.returnResponse(response);
doctorList = Doctorlist.fromJson(responseJson);
print(doctorList);
return Doctorlist.fromJson(responseJson);
} else {
return null;
}
} on SocketException {
return null;
}
}
}
my ui List View builder page :
class _DoctorState extends State<Doctor> {
Doctorlist doctorList;
bool fav = true;
@override
void initState() {
doctorList =
Provider.of<DoctorListProvider>(context, listen: false).doctorList;
super.initState();
}
@override
Widget build(BuildContext context) {
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: doctorList.data.length,
// itemCount: 2,
// reverse: false,
primary: true,
itemBuilder: (BuildContext context, int index) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
child: Flexible(
child:
Container(child:
InkWell(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => Doctordetails()));
},
child:
Card(
// color: Color(0xff29ABE2),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: 100,
),
child: Padding(
padding: EdgeInsets.only(
left: 10,
right: 0,
top: 10),
child: Row(
children: <Widget>[
Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment
.start,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <
Widget>[
Container(
decoration:
new BoxDecoration(
borderRadius:
BorderRadius.all(
const Radius.circular(100.0)),
border: Border.all(
color: Colors
.black),
),
height: 70,
width: 70,
child:
ClipRRect(
borderRadius:
BorderRadius.circular(
200),
child: Image
.asset(
'assets/images/registration/profile_side.png',
fit: BoxFit
.fill,
),
),
),
SizedBox(
width: MediaQuery.of(
context)
.size
.height /
80,
),
Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <
Widget>[
Text(
"no",
style: TextStyle(
fontFamily:
"SansBold",
fontSize:
15,
color:
Colors.black),
),
Text(
"no",
style: TextStyle(
fontFamily:
"SansRegular",
fontSize:
15,
color:
Colors.black),
),
SizedBox(
height: 5,
),
SizedBox(
height: MediaQuery.of(context)
.size
.height /
13,
width: MediaQuery.of(context)
.size
.width /
1.9,
child:
AutoSizeText(
'no ',
style: TextStyle(
fontSize:
20),
maxLines:
3,
),
)
],
),
Container(
child:
IconButton(
onPressed:
() {
setState(
() {
fav =
!fav;
});
},
icon: fav
? Image.asset(
"assets/images/appointment/favourite_unselected.png")
: Image.asset(
"assets/images/appointment/favourite_select.png"),
))
],
),
SizedBox(
height: 5,
),
Row(
children: <
Widget>[
Container(
child: IconButton(
icon: Image
.asset(
"assets/images/appointment/last_appointment.png"),
onPressed:
null),
),
SizedBox(
width: 10,
),
Text(
"Last appointment date",
style: TextStyle(
fontFamily:
"SansRegular",
fontSize:
15,
color: Colors
.black),
)
],
),
Container(
child: Text(
"06-08-2020"),
),
],
),
SizedBox(
width: MediaQuery.of(
context)
.size
.width /
40,
),
],
))))))))
],
);
},
),
My Json response Look Like this.
{
"status": 1,
"message": "success",
"data": [
{
"id": "1",
"mobile": "7",
"user_image": "https://hghjfjd.com",
"emr_number": "er-357",
"hospital": "ff",
"status": "1",
"doctor_name": "sanje",
"doc_role": "dfd",
"email": "doctor@gmail.com",
"gender": "Male",
"address": "test mode",
"city": "england",
"state": "tn",
"pincode": "633211",
"clinic_name": "clinic",
"appointment_date": "2020-09-07",
"favourite": "No"
},
回答1:
Try this:
): Edit initState()
method to:
@override
void initState(){
WidgetsBinding.instance.addPostFrameCallback((_) => _afterLayout(context));
}
): Now you can load items in _afterLayout(context)
method:
_afterLayout(BuildContext context) async {
var docState = Provider.of<DoctorListProvider>(context);
docState.setDoctorList(await docState.doctorlist());
}
): Update this class DoctorListProvider
:
class DoctorListProvider extends ChangeNotifier {
Doctorlist _doctorList;
Doctorlist get getDoctorList => _doctorList;
set setDoctorList(Doctorlist input){
_doctorList = input;
notifierListners();
}
...
}
): Finally use this in you UI :
class _DoctorState extends State<Doctor> {
bool fav = true;
@override
void initState(){
WidgetsBinding.instance.addPostFrameCallback((_) => _afterLayout(context));
}
@override
Widget build(BuildContext context) {
var docState = Provider.of<DoctorListProvider>(context);
return docState.getDoctorList == null ? Container(child: CircularProgressIndicator()) :
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: docState.getDoctorList.data.length,
// itemCount: 2,
// reverse: false,
primary: true,
itemBuilder: (BuildContext context, int index) {
来源:https://stackoverflow.com/questions/63829443/how-to-get-listview-builder-data-using-api-response-in-flutter-ui-using-provider