jsonflutterfastapihttp-getflutter-futurebuilder

Flutter, converting json into list issue: making listview, futurebuilder from data from http.get


I am trying to receive data (list) from the database and save the data as list type, and show the data in front end by using futurebuilder, listview. But I guess the code could not convert the json from data into the list format. Please help.

This is party class in flutter

import 'package:flutter_application_1/models/user.dart';
import 'package:json_annotation/json_annotation.dart';

class Party {
  final String date_time;
  final String destination;
  final String departure;
  final int max_recruitment;
  final int cur_recruitment;
  final String party_type;
  final String party_recruiter_id;
  final List<String> party_member_id;
  final double departure_party_Lat;
  final double departure_party_Lng;
  final double destination_party_Lat;
  final double destination_party_Lng;

  const Party(
    this.date_time,
    this.destination,
    this.departure,
    this.max_recruitment,
    this.cur_recruitment,
    this.party_type,
    this.party_recruiter_id,
    this.party_member_id,
    this.departure_party_Lat,
    this.departure_party_Lng,
    this.destination_party_Lat,
    this.destination_party_Lng,
  );

  factory Party.fromJson(Map<String, dynamic> json) {
    return Party(
        json['date_time'] as String,
        json['destination'] as String,
        json['departure'] as String,
        json['max_recruitment'] as int,
        json['cur_recruitment'] as int,
        json['party_type'] as String,
        json['party_recruiter_id'] as String,
        json['party_member_id'] as List<String>,
        json['departure_party_Lat'] as double,
        json['departure_party_Lng'] as double,
        json['destination_party_Lat'] as double,
        json['destination_party_Lng'] as double);
  }

  // static Party fromJson(json) => Party(
  //       date_time: json['date_time'],
  //       destination: json['destination'],
  //       departure: json['departure'],
  //       max_recruitment: json['max_recruitment'],
  //       cur_recruitment: json['cur_recruitment'],
  //       party_type: json['party_type'],
  //       party_recruiter_id: json['party_recruiter_id'],
  //       party_member_id: List<String>.from(json['party_member_id']),
  //       departure_party_Lat: json['departure_party_Lat'],
  //       departure_party_Lng: json['departure_party_Lng'],
  //       destination_party_Lat: json['destination_party_Lat'],
  //       destination_party_Lng: json['destination_party_Lng'],
  //     );
}

This is method that receive data from database:

 Future getData() async {
    var response = await http.get(
      Uri.parse('http://10.0.2.2:8000/party/find'),
      headers: <String, String>{
        'Content-Type': 'application/x-www-form-urlencoded'
      },
    );
    if (response.statusCode == 200) {
      List<dynamic> jsonDataList = json.decode(response.body);

      List<Party> parties =
          jsonDataList.map((json) => Party.fromJson(json)).toList();

      print(parties);
      return response;

      // List <Party> = parties =  List<Party>.from(json.decode(response.body));
//       Iterable l = json.decode(response.body);
// List<Party> posts = List<Party>.from(l.map((model)=> Party.fromJson(model)));
      // List<Party> parties;
      // parties = (json.decode(response.body) as List)
      //     .map((i) => parties.(i))
      //     .toList();
      // print('success');

      // final parsed =
      //     (jsonDecode(response.body) as List).cast<Map<String, dynamic>>();

      // parsed.map<Party>((json) => Party.fromJson(json).toList());

      // List jsonData = json.decode(response.body);
      // print(jsonData[0]);
      // print(jsonData.length);

      // List<dynamic> jsonDataList = jsonDecode(response.body);
      // print('success');

      // print(jsonDataList.length);
      // print(jsonDataList[1]);
      // print("\n");
      // print("\n");

      // print(jsonDataList[1]);
      // List<Party> parties = [];
      // for (var u in jsonDataList) {
      //   Party party = Party(
      //       u['date_time'],
      //       u['destination'],
      //       u['departure'],
      //       u['max_recruitment'],
      //       u['cur_recruitment'],
      //       u['party_type'],
      //       u['party_recruiter_id'],
      //       u['party_member_id'],
      //       u['departure_party_Lat'],
      //       u['departure_party_Lng'],
      //       u['destination_party_Lat'],
      //       u['destination_party_Lng']);

      //   parties.add(party);
      // }
      // print(parties.length);
      // return jsonDataList;
    } else {
      print("bad");
      return;
    }
  }

and the following information is given to response(variable in above code), which is json type:

[
  {
    "_id": "6512b53f7e4483304e0b63c2",
    "date_time": "2024-05-17 00:00:00",
    "destination": "",
    "departure": "",
    "max_recruitment": 4,
    "cur_recruitment": 0,
    "party_type": "carpool",
    "party_recruiter_id": "65129c93ab78fa66247e2846",
    "party_member_id": [
      ""
    ],
    "party_Lat": 36.09891,
    "party_Lng": 129.3833
  },
  {
    "_id": "654f5ad41cbfe05e6a363c3c",
    "date_time": "string",
    "destination": "string",
    "departure": "string",
    "max_recruitment": 0,
    "cur_recruitment": 0,
    "party_type": "string",
    "party_recruiter_id": "654f2e7e9cb296bce3858e89",
    "party_member_id": [
      "string"
    ],
    "departure_party_Lat": 0,
    "departure_party_Lng": 0,
    "destination_party_Lat": 0,
    "destination_party_Lng": 0
  },
  {
    "_id": "654f7b10da51caca2ea6a6ac",
    "date_time": "340924",
    "destination": "string",
    "departure": "string",
    "max_recruitment": 0,
    "cur_recruitment": 0,
    "party_type": "string",
    "party_recruiter_id": "65323a4812f3118027b4c791",
    "party_member_id": [
      "string"
    ],
    "departure_party_Lat": 0,
    "departure_party_Lng": 0,
    "destination_party_Lat": 0,
    "destination_party_Lng": 0
  },
  {
    "_id": "654f7bb9bfa913acae51abcc",
    "date_time": "string",
    "destination": "string",
    "departure": "string",
    "max_recruitment": 0,
    "cur_recruitment": 0,
    "party_type": "string",
    "party_recruiter_id": "kkh",
    "party_member_id": [
      "string"
    ],
    "departure_party_Lat": 0,
    "departure_party_Lng": 0,
    "destination_party_Lat": 0,
    "destination_party_Lng": 0
  }
]

and I am trying to make futurebuilder, listview after sorting data from database to list with Party class:

        FutureBuilder(
            future: getData(),
            builder: (context, snapshot) {
              if (snapshot.data == null) {
                print(snapshot);
                return CircularProgressIndicator();
              } else {
                return ListView.builder(
                    itemCount: snapshot.data!.legnth,
                    itemBuilder: (BuildContext context, int index) {
                      return Padding(
                        padding: const EdgeInsets.all(8.0),
                        child:
                        card_partylist(
                            snapshot.data[index].date_time,
                            snapshot.data[index].party_type,
                            snapshot.data[index].dateTime,
                            snapshot.data[index].departure,
                            snapshot.data[index].destination,
                            '&snapshot.data[index].cur_recruitment/&snapshot.data[index].max_recruitment'),
                      );
                    });
              }
            }),
'''

card_play_list is:
'''
Widget card_partylist(String inputdate, String inputType, String inputTime,
    String inputStart, String inputEnd, String inputStatus) {
  int contextSpace = 1;
  int contextFont = 3;

  return Container(
    height: 90,
    decoration: BoxDecoration(
        color: Colors.white,
        border: Border(bottom: BorderSide(width: 1, color: Colors.black))),
    child: Row(
      children: [
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(
          flex: contextFont,
          child: Text(inputdate),
        ),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(flex: contextFont, child: Text(inputType)),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(
            flex: contextFont,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Expanded(
                  flex: 1,
                  child: SizedBox(),
                ),
                Expanded(flex: 2, child: Text(inputTime)),
                Expanded(
                  flex: 2,
                  child: Text(inputStart),
                )
              ],
            )),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(flex: contextFont, child: Text(inputEnd)),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(
          flex: contextSpace,
          child: SizedBox(),
        ),
        Expanded(flex: contextFont, child: Text(inputStatus)),
      ],
    ),
  );
}

Solution

  • The problem is in your getData() function and your Party class model, you have converted the response to the Party model class and instead of returning List of parties you returned the response. I would suggest the following changing and trying again.

        // Here I changed the party_recruiter_id from list string to 
        // list dynamic because the API doesn't return list of string
    
        class Party {
          final String date_time;
          final String destination;
          final String departure;
          final int max_recruitment;
          final int cur_recruitment;
          final String party_type;
          final String party_recruiter_id;
          final List<dynamic> party_member_id;
          final double departure_party_Lat;
          final double departure_party_Lng;
          final double destination_party_Lat;
          final double destination_party_Lng;
    
         const Party(
           this.date_time,
           this.destination,
           this.departure,
           this.max_recruitment,
           this.cur_recruitment,
           this.party_type,
           this.party_recruiter_id,
           this.party_member_id,
           this.departure_party_Lat,
           this.departure_party_Lng,
           this.destination_party_Lat,
           this.destination_party_Lng,
       );
    
           factory Party.fromJson(Map<String, dynamic> json) {
             return Party(
             json['date_time'] as String,
             json['destination'] as String,
             json['departure'] as String,
             json['max_recruitment'] as int,
             json['cur_recruitment'] as int,
             json['party_type'] as String,
             json['party_recruiter_id'] as String,
             json['party_member_id'] as List<dynamic>,
             json['departure_party_Lat'] as double,
             json['departure_party_Lng'] as double,
             json['destination_party_Lat'] as double,
             json['destination_party_Lng'] as double);
             }
          }
    

    Here is the updated getData() function

    Future<List<Party>> getData() async {
    final response = await http.get(
      Uri.parse('http://10.0.2.2:8000/party/find'),
      headers: <String, String>{
        'Content-Type': 'application/x-www-form-urlencoded'
      },
    );
    if (response.statusCode == 200) {
      // Here i declare the jsonDecode typ as List<dynamic> to give it the right type
      final jsonData = jsonDecode(response.body) as List<dynamic>;
      // Here i cast the List<dynamic> jsonData to List<Map<String,dynamic>>
      final castedData = List<Map<String, dynamic>>.from(jsonData);
      // Here i convert the castedData to the a List<Party> model
      final parties = castedData.map(Party.fromJson).toList();
      print(parties);
      return parties;
    } else {
      print("bad");
      return <Party>[];
      }
    }
    

    This will give you a List of parties that you can use later.

    I would also suggest the following changes for your ListView class.

    FutureBuilder<List<Party>>(
    future: getData(),
    builder: (context, snapshot) {
      if (snapshot.hasData && snapshot.data != null) {
        final data = snapshot.data!;
        return ListView.builder(
          itemCount: data.length,
          itemBuilder: (BuildContext context, int index) {
            final party = data[index];
            return Padding(
              padding: const EdgeInsets.all(8.0),
              child: card_partylist(
                  party.date_time,
                  party.party_type,
                  party.dateTime,
                  party.departure,
                  party.destination,
                  '&snapshot.data[index].cur_recruitment/&snapshot.data[index].max_recruitment'),
            );
          },
        );
      } else if (snapshot.hasError) {
        return const Center(child: Icon(Icons.error_outline));
      } else {
        return const Center(child: CircularProgressIndicator());
        }
      },
    );
    

    Let me know if this worked for you and fixed your issue.