Alex Wright
Alex Wright

Reputation: 627

How to fetch an array data from API and map it to the dart object?

I'm trying to use Flutter documentation to map an array data (comes from API) to the dart object. The documentation uses a single Json object, not an array. I have the following codes:

Json data:

[
    {
        "channelId" :   1
        "channelTitle"  :   "Photos"
        "channelImage"  :   pr01.jpg
        "channelLastPost"   :   null
        "lastUpdate"    :   null
        "userRef"   :   1
    },
    {
        "channelId" :   2
        "channelTitle"  :   "Science"
        "channelImage"  :   pr02.jpg
        "channelLastPost"   :   "For test ...."
        "lastUpdate"    :   "2023-01-03"
        "userRef"   :   1
    }

]

ChannelListModel.dart:

class ChannelListModel {
  String creator;
  String? image;
  String title;
  String lastPost;
  String lastUpdate;

  ChannelListModel(
      {required this.creator,
      required this.image,
      required this.title,
      required this.lastPost,
      required this.lastUpdate});

  factory ChannelListModel.fromJson(Map<String, dynamic> json) {
    return ChannelListModel(
        creator: json['userRef'],
        image: json['channelImage'],
        title: json['channelTitle'],
        lastPost: json['channelLastPost'],
        lastUpdate: json['lastUpdate']);
  }
  Map<String, dynamic> toJson() {
    return {
      "userRef" : creator,
      "channelImage" : image,
      "channelTitle" : title,
      "channelLastPost" : lastPost,
      "lastUpdate" : lastUpdate
    };
  }
}

HttpRequest.dart:

class HttpServices {
  Future<List<ChannelListModel>> getChannelList() async {
    var url = base.BaseURL.channelListUrl;
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      return List<ChannelListModel>.fromJson(jsonDecode(response.body)); //I have problem in this line
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load album');
    }
  }
}

ChannelPage.dart:

class _ChannelsState extends State<Channels> {

  List<ChannelListModel> channels = [];

  @override
  void initState() {
    super.initState();
    channels  = getChannelsFromHttp(); // A valid array object needs to be provided here.
  }

  getChannelsFromHttp()async{
    var httpService = HttpServices();
    var result = await httpService.getChannelList();
    return result;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: channels.length,
        itemBuilder: (context, index) =>
            ChannelCard(channelModel: channels[index]),
      ),
    );
  }
}

I want to classify my codes so I decided to provided different dart files for each part. How can I fix my code?

Upvotes: 1

Views: 898

Answers (2)

Soliev
Soliev

Reputation: 1376

Your fromJson factory returns single ChannelListModel. You can't use List<ChannelListModel>.fromJson. Instead iterate through List and convert each json to ChannelListModel

class HttpServices {
  Future<List<ChannelListModel>> getChannelList() async {
    var url = base.BaseURL.channelListUrl;
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      //return List<ChannelListModel>.fromJson(jsonDecode(response.body));
      final data = jsonDecode(response.body) as List<dynamic>;
      return data.map((e) => ChannelListModel.fromJson(e as Map<String, dynamic>))
        .toList();

    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load album');
    }
  }
}

Upvotes: 0

rrttrr
rrttrr

Reputation: 1846

Instead of

returnList<ChannelListModel>.fromJson(jsonDecode(response.body));

Try this code,

List<ChannelListModel> channels = [];
final res = jsonDecode(response.body);
channels.addAll(List<ChannelListModel>.from(
  (res).map((x) => ChannelListModel.fromJson(x))));
return channels;

Added based on comments


@override
  void initState() {
    super.initState();
    getChannelsFromHttp();
  }

  getChannelsFromHttp()async{
    var httpService = HttpServices();
    var result = await httpService.getChannelList();
    setState((){
     channels = result;
    });
  }

Upvotes: 1

Related Questions