E. Biagi
E. Biagi

Reputation: 482

Error listing information with rest API with Flutter

I'm trying to list information from an API remaining on the screen. I have this method:

late List<MyModel> _listAll; // original list fetched from API
late List<MyModel> _displayList; 
.
.

void _ListTransaction() async {
    
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String token = prefs.getString("userToken") ?? "";

    dynamic data = await http.get(Uri.parse('....'), headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': '$token',
    });
    
    List<MyModel> listAll= [];

    for (var u in data) {
      MyModel myModel = MyModel.fromJson(u);
      print(myModel);
      listAll.add(myModel);
    }

    setState(() {
      _listAll = listAll;
      _displayList = _listAll ;
    });
  }

Here I get the error:

_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable')

I also tried this approach:

void _ListTransaction() async {

    SharedPreferences prefs = await SharedPreferences.getInstance();
    String token = prefs.getString("userToken") ?? "";

    dynamic data = await http.get(Uri.parse('....'), headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': '$token',
    });

   var list = json.decode(data.body);
    print(list);

    setState(() {
      _listAll = list;
      _displayedList = _petrolList;
    });
    
  }

But here I get the error:

_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List')

You guys could help me with this error. I appreciate any comments!

UPDATE I used this approach too, but to no avail!

Here is the structure of my json.decode(data.body); enter image description here

MyModel:

class TransactionModel {
  int? month;
  int? year;
  double? balanceFull;
  double? balanceMonth;
  ExpenseModel? expenseModel;
  RevenueModel? revenueModel; 

  TransactionModel();

  Transactions() {
    month = 00;
    year = 0000;
    balanceFull = 0;
    balanceMonth = 0;
  }

  TransactionModel.fromJson(Map<String, dynamic> json) {
    month = json['month'];
    year = json['year'];
    balanceFull = json['balanceFull'];
    balanceMonth = json['balanceMonth'];
    expenseModel = json['expenseModel'];
    revenueModel = json['revenueModel'];
  }

Upvotes: 2

Views: 232

Answers (3)

Lucas
Lucas

Reputation: 1

Last week i had a similar problem.

I solved it using the follow code:

  int _offset = 0;
  List<Skeleton> array_news = [];

  Future<List<Skeleton>> fetchNews(int offset) async {
    final response = await http.get(Uri.parse(
        'http://192.168.15.5:5000//custom-events?limit=3&offset=$offset'));

    return parseNews(response.body);
  }

  List<Skeleton> parseNews(String responseBody) {
    final parsed =
        json.decode(responseBody)['events'].cast<Map<String, dynamic>>();
    return parsed.map<Skeleton>((json) => Skeleton.fromJson(json)).toList();
  }

  void executeScript(int offset) async {
    List news = await fetchNews(offset);
    setState(() {
      news.forEach((data) {
        array_news.add(Skeleton(
            id: data.id,
            title: data.title,
            page_link: data.page_link,
            image_link: data.image_link));
      });
    });
  }

Skeleton code:

class Skeleton {
  int id = 0;
  String title = '';
  String page_link = '';
  String image_link = '';

  Skeleton(
      {required this.id,
      required this.title,
      required this.page_link,
      required this.image_link});

  Skeleton.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    title = json['title'];
    page_link = json['page_link'];
    image_link = json['image_link'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['title'] = this.title;
    data['page_link'] = this.page_link;
    data['image_link'] = this.image_link;
    return data;
  }
}

After that just access array_news list data through index.

For example:

array_news[0].title;

Upvotes: 0

Tom3652
Tom3652

Reputation: 2967

You should do something like this :

var result = json.decode(data.body);
List<Map<String, dynamic>> list = (result as List).map((e) => e as Map<String, dynamic>).toList();
list.forEach((element) {
  _listAll.add(MyModel.fromJson(element));
}

In my case this works because i have a list of Map<String, dynamic> in my result var from my API.

EDIT : Based on your comment and the screenshot, you should do this :

Map<String, dynamic> result = json.decode(data.body) as Map<String, dynamic>;
result.forEach((element) {
  _listAll.add(MyModel.fromJson(element));
}

And in TransactionModel :

TransactionModel.fromJson(Map<String, dynamic> json) {
    month = json['month'];
    year = json['year'];
    balanceFull = json['balanceFull'];
    balanceMonth = json['balanceMonth'];
    List<Map<String, dynamic>> expenseList = (json["expenses"] as List).map((e) => e as Map<String, dynamic>).toList();
    List<Map<String, dynamic>> revenueList = (json["revenues"] as List).map((e) => e as Map<String, dynamic>).toList();
    expenseModel = ExpenseModel.fromJson(list.first) // You can loop
    revenueModel = RevenueModel.fromJson(revenueList.first) // Same
  }

The idea is that you need to convert every nested model you have to Map<String, dynamic> before making the conversion.

I had the sameissue not so long ago.

Upvotes: 0

I think that the error is that _listAll is a type list of the MyModel, but the list in the "setState" method is Map<String, dynamic>.

I hope to help you.

Upvotes: 0

Related Questions