Home > Mobile >  LateInitializationError: Field 'plans' has not been initialized. When Parsing JSON and Dis
LateInitializationError: Field 'plans' has not been initialized. When Parsing JSON and Dis

Time:06-08

Flutter newbie here! I'm trying to build a list view from an api response.

I am getting a JSON response:

{
    "data": [
        {
            "id": "102",
            "operator_id": "Airtel",
            "circle_id": "Andhra Pradesh",
            "recharge_amount": "10",
            "recharge_talktime": "7.47",
            "recharge_validity": "N.A.",
            "recharge_short_desc": "Recharge of Rs. 10 by Airtel",
            "recharge_long_desc": "Talktime: Rs.7.47",
            "recharge_type": "Top up",
            "updated_at": "02-06-2022 11:27:02"
        },
        {
            "id": "103",
            "operator_id": "Airtel",
            "circle_id": "Andhra Pradesh",
            "recharge_amount": "20",
            "recharge_talktime": "14.95",
            "recharge_validity": "N.A.",
            "recharge_short_desc": "Recharge of Rs. 20 by Airtel",
            "recharge_long_desc": "Talktime: Rs.14.95",
            "recharge_type": "Top up",
            "updated_at": "02-06-2022 11:27:02"
        },
        {
            "id": "105",
            "operator_id": "Airtel",
            "circle_id": "Andhra Pradesh",
            "recharge_amount": "100",
            "recharge_talktime": "81.75",
            "recharge_validity": "N.A.",
            "recharge_short_desc": "Recharge of Rs. 100 by Airtel",
            "recharge_long_desc": "Talktime: Rs.81.75",
            "recharge_type": "Top up",
            "updated_at": "02-06-2022 11:27:02"
        },
        {
            "id": "106",
            "operator_id": "Airtel",
            "circle_id": "Andhra Pradesh",
            "recharge_amount": "500",
            "recharge_talktime": "423.73",
            "recharge_validity": "N.A.",
            "recharge_short_desc": "Recharge of Rs. 500 by Airtel",
            "recharge_long_desc": "Talktime: Rs.423.73",
            "recharge_type": "Top up",
            "updated_at": "02-06-2022 11:27:02"
        }
       ]    
}

I use this Model Class to convert JSON to Dart Objects:

Plans plansFromJson(String str) => Plans.fromJson(json.decode(str));

String plansToJson(Plans data) => json.encode(data.toJson());
 
class Plans {
    Plans({
        required this.data,
    });

    List<Datum> data;

    factory Plans.fromJson(Map<String, dynamic> json) => Plans(
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
    };
}

class Datum {
    Datum({
        required this.id,
        required this.operatorid,
        required this.circleid,
        required this.rechargeAmount,
        required this.rechargeTalktime,
        required this.rechargeValidity,
        required this.rechargeShortdesc,
        required this.rechargeLongdesc,
        required this.rechargeType,
        required this.updatedAt,
    });

    String id;
    String operatorid;
    String circleid;
    String rechargeAmount;
    String rechargeTalktime;
    String rechargeValidity;
    String rechargeShortdesc;
    String rechargeLongdesc;
    String rechargeType;
    String updatedAt;

    factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        id: json["id"],
        operatorid: json["operatorid"],
        circleid: json["circleid"],
        rechargeAmount: json["recharge_amount"],
        rechargeTalktime: json["recharge_talktime"],
        rechargeValidity: json["recharge_validity"],
        rechargeShortdesc: json["recharge_shortdesc"],
        rechargeLongdesc: json["recharge_longdesc"],
        rechargeType: json["recharge_type"],
        updatedAt: json["updated_at"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "operatorid": operatorid,
        "circleid": circleid,
        "recharge_amount": rechargeAmount,
        "recharge_talktime": rechargeTalktime,
        "recharge_validity": rechargeValidity,
        "recharge_shortdesc": rechargeShortdesc,
        "recharge_longdesc": rechargeLongdesc,
        "recharge_type": rechargeType,
        "updated_at": updatedAt,
    };
}

API Request Method:

Future<Plans> getPlanDetails(
      String operator, String circle, String rechargeType) async {
    var planUrl = Uri.parse(
        'https://api.datayuge.com/v6/rechargeplans/?apikey=$datayugeApiKey&operator_id=$operator&circle_id=$circle&recharge_type=$rechargeType&limit=50&order_by=recharge_amount');
    debugPrint(planUrl.toString());
    final response = await http.get(planUrl);
    debugPrint(response.body);
    String jsonString = response.body;
    final plans = plansFromJson(jsonString);
    return plans;
  }

When I try to build a listview from this data, I get the LateInitializationError. Everything works fine when I load a local String as JSON. I get this error only when I'm fetching the data from API.

Stateful Widget:

class RechargePlansView extends StatefulWidget {
  RechargePlansView({Key? key}) : super(key: key);

  @override
  State<RechargePlansView> createState() => _RechargePlansViewState();
}

class _RechargePlansViewState extends State<RechargePlansView> {
List<Datum> data = [];
late Plans plans;

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Recharge Plans')),
      body: Text('Recharge Plans view'),
       ListView.builder(
           itemCount: widget.plans.data.length,
           itemBuilder: (context, index) {
             return ListTile(
               leading: CircleAvatar(
                 radius: 28,
                 child: Center(
                   child: Text(
                       '\u{20B9}${plans.data[index].rechargeAmount.toString()}'),
                 ),
               ),
               title: Text(
                   'Talktime: ${plans.data[index].rechargeAmount} Validity: ${plans.data[index].rechargeValidity}'),
               subtitle: Text(plans.data[index].rechargeShortDesc),
             );
           }),
    );
  }
}

CodePudding user response:

you defined: late Plans plans;

but which line you initialize this attribute?

also in which line you called api method?

actually your plans attr is null!

CodePudding user response:

I solved this by Initializing Plans in setState().

class _RechargePlansViewState extends State<RechargePlansView> {

  @override
  void initState() {
    super.initState();
    widget.getPlanDetails().then((value) {
      setState(() {
        plans = value;
      });
    });
  }
}
  • Related