Search code examples
flutterdartbloccubit

'List<dynamic>' is not a subtype of type 'Map<String, dynamic>' flutter cubit


I am trying get and show results with Mock API but when i try to call api and pass data to json conveted class it throws an error shown like this

Error

  I/flutter (15755): #0      NetworkService.getData (package:beinex_test/network/network_service.dart:20:51) I/flutter (15755): <asynchronous suspension> [log] get Valuetype 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>' 
    [{id: 1032, title: There are about as many definitions of art as there are ...
  ^

API Class

class NetworkService {
var dio=Dio();
  Future<dynamic> getData() async {
    try {
     
      dio.options.headers['Content-Type'] = 'application/json';
      var response = await dio.get(ApiUrls.baseUrl);

      if (response.statusCode == 200) {
        return DataGridResponse.fromJson(response.data);
      } else {
        return response.statusCode.toString();
      }
    } catch (e, stackTrace) {
      print(stackTrace.toString());
      return e.toString();
    }
  }

}

Cubit

class DashboardCubit extends Cubit<DashboardState> {
  Repository repository;
  DashboardCubit(this.repository) : super(DashboardInitial());
  void getMockData() async{
    emit(DashboardLoading());
    repository.getMockApi().then((value){
      log("get Value${value}");
      emit(DashboardLoading());
      if(value is DataGridResponse){

        emit(DashboardLoaded(value));
      }else{
        emit(DashboardLoadedError("failed to fetch data!!"));
      }
    });
  }
}

Converted Json Class

import 'dart:convert';

class DataGridResponse {
    int id;
    String title;
    String itemId;
    bool active;
    DateTime date;
    bool overdue;
    ItemType1? itemType1;
    ItemType1? itemType2;
    List<ItemType1>? level1;
    List<ItemType1>? level2;
    Status status;

    DataGridResponse({
        required this.id,
        required this.title,
        required this.itemId,
        required this.active,
        required this.date,
        required this.overdue,
        this.itemType1,
        this.itemType2,
        this.level1,
        this.level2,
        required this.status,
    });

    factory DataGridResponse.fromJson(Map<String, dynamic> json) => DataGridResponse(
        id: json["id"],
        title: json["title"],
        itemId: json["item_id"],
        active: json["active"],
        date: DateTime.parse(json["date"]),
        overdue: json["overdue"],
        itemType1: json["item_type1"] == null ? null : ItemType1.fromJson(json["item_type1"]),
        itemType2: json["item_type2"] == null ? null : ItemType1.fromJson(json["item_type2"]),
        level1: json["level1"] == null ? [] : List<ItemType1>.from(json["level1"]!.map((x) => ItemType1.fromJson(x))),
        level2: json["level2"] == null ? [] : List<ItemType1>.from(json["level2"]!.map((x) => ItemType1.fromJson(x))),
        status: Status.fromJson(json["status"]),
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "title": title,
        "item_id": itemId,
        "active": active,
        "date": "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
        "overdue": overdue,
        "item_type1": itemType1?.toJson(),
        "item_type2": itemType2?.toJson(),
        "level1": level1 == null ? [] : List<dynamic>.from(level1!.map((x) => x.toJson())),
        "level2": level2 == null ? [] : List<dynamic>.from(level2!.map((x) => x.toJson())),
        "status": status.toJson(),
    };
}

class ItemType1 {
    String? value;
    String? color;

    ItemType1({
        this.value,
        this.color,
    });

    factory ItemType1.fromJson(Map<String, dynamic> json) => ItemType1(
        value: json["value"],
        color: json["color"],
    );

    Map<String, dynamic> toJson() => {
        "value": value,
        "color": color,
    };
}

class Status {
    int currentCount;
    int totalCount;

    Status({
        required this.currentCount,
        required this.totalCount,
    });

    factory Status.fromJson(Map<String, dynamic> json) => Status(
        currentCount: json["current_count"],
        totalCount: json["total_count"],
    );

    Map<String, dynamic> toJson() => {
        "current_count": currentCount,
        "total_count": totalCount,
    };
}

Solution

  • Ok, I looked through your github project and you can do the following changes to make it work:


    network_service.dart:

    Change

        return DataGridResponse.fromRawJson(response.data);
    

    to

        return response.data.map<DataGridResponse>((e)=>DataGridResponse.fromJson(e)).toList();
    

    dashboard_state.dart:

    Change

    DataGridResponse mocklistdata;
    

    to

    List<DataGridResponse> mocklistdata;
    

    dashboard_cubit.dart:

    Change

      if(value is DataGridResponse){
    

    to

      if(value is List<DataGridResponse>){
    

    dashboard.dart:

    Change

            mockListItem.add(state.mocklistdata);
    

    to

            mockListItem = state.mocklistdata;