#api #flutter #dart #provider
#API #flutter #dart #поставщик
Вопрос:
Я пытаюсь получить ответ от поставщика и выполнить выборку на странице пользовательского интерфейса, но когда я пытаюсь добавить ответ в пользовательский интерфейс, он показывает ошибку The getter 'data' was called on null. Receiver: null Tried calling: data
В этой строке:
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: doctorList.data.length,
primary: true,
это правильное приложение или необходимо изменить модальный класс или интеграцию пользовательского интерфейса.
я получаю доступ к данным через doctorList.data.-> данные datas.
Мой модальный класс ответа.
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,
};
}
Мой класс провайдера:
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;
}
}
}
моя страница конструктора просмотра списка пользовательского интерфейса :
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,
),
],
))))))))
],
);
},
),
Мой ответ Json выглядит следующим образом.
{
"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:
Попробуйте это:
): Изменить initState()
метод для:
@override
void initState(){
WidgetsBinding.instance.addPostFrameCallback((_) => _afterLayout(context));
}
): Теперь вы можете загружать элементы в _afterLayout(context)
метод:
_afterLayout(BuildContext context) async {
var docState = Provider.of<DoctorListProvider>(context);
docState.setDoctorList(await docState.doctorlist());
}
): Обновите этот класс DoctorListProvider
:
class DoctorListProvider extends ChangeNotifier {
Doctorlist _doctorList;
Doctorlist get getDoctorList => _doctorList;
set setDoctorList(Doctorlist input){
_doctorList = input;
notifierListners();
}
...
}
): Наконец, используйте это в своем пользовательском интерфейсе :
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) {
Комментарии:
1. Да, я проверил, что в списке есть данные @Hakiza
2. Где вы вызываете эту функцию
Future<Doctorlist> doctorlist() async {
?3. в отдельном файле doctorListProvider. обновленный код. и доступ к нему в классе пользовательского интерфейса
4. var docState = Provider.of<DoctorListProvider>(контекст); docState.getDoctorList == null ? Контейнер (дочерний элемент: CircularProgressIndicator()): где их определить? я новичок, извините; ( спасибо, это будет полезно. @Hazika
5. Вы должны определить их в
@override Widget build(BuildContext context) {
функции. Эта функция возвращаетWidget
,return docState.getDoctorList == null ? Container(child: CircularProgressIndicator()) : ...
Ответ №2:
Как я обработал эту ошибку, я удалил или присвоил «» нулевому значению. Это потому, что данные, которые вы извлекаете из своего ответа API, имеют нулевое значение. Если вы знаете, какое значение может быть null, вы можете назначить пустое строковое значение и устранить ошибку.
Вот коды того, как я это сделал. Это непрофессионально, но оно выполняет вашу работу.
Комментарии:
1. Кроме того, лучше использовать Consumer вместо функции initState.
2. Пожалуйста, не используйте изображение для кода. Он потребляет больше ресурсов и не может быть скопирован / вставлен.
3. извините, я не понял это правильно @laurent. о каком изображении вы говорите? Изображение, о котором я вставил выше?
4. Да, ваш пример кода — это скриншот.