How to get ListView builder data using api response in flutter ui using provider

狂风中的少年 提交于 2021-02-11 12:35:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!