Search code examples
flutterlisthttpmodelmapping

type '(dynamic) => ProductModel' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform'


Tried almost every solution. No luck :(

Future<List<ProductModel>> getProducts() async {
    try {
      final response = await apiService.sendRequest.get('/product');
      if (response.data != null) {
        print("Data == $response");
       
        return response.data
            .map((e) => ProductModel.fromJson(e.toMap()))          // error is thrown here
            .toList();     
      }
      return <ProductModel>[];
    } catch (ex) {
      // return <ProductModel>[];
      rethrow;
    }
  }

response is:

  {
  "status": "SUCCESS",
  "message": "Records found",
  "data": [
    {
      "_id": "634acde1a556b0cd25dfffb1",
      "typeOfProduct": "Cake",
      "name": "Designer Cake",
      "primaryPrice": 700,
      "primaryDiscountedPrice": 560,
      "secondaryPrice": 1400,
      "secondaryDiscountedPrice": 1120,
      "categories": [
      ....
      ],
      "tags": [
       ...
      ],
      "description": "This is the best cake ",
      "images": [
       ...
      ],
      "quantity": "1 Box",
      "__v": 0,
      "primaryDiscountedRate": 20,
      "secondaryDiscountedRate": 20
    },
 ]
}

Product Model is :

class ProductModel {
  ProductModel({
    required this.id,
    required this.typeOfProduct,
    required this.name,
    required this.primaryPrice,
    this.primaryDiscountedPrice,
    this.secondaryPrice,
    this.secondaryDiscountedPrice,
    required this.categories,
    required this.tags,
    this.description,
    required this.images,
    this.quantity,
    this.primaryDiscountedRate,
    this.secondaryDiscountedRate,
  });

  ObjectId id;
  String typeOfProduct;
  String name;
  int primaryPrice;
  int? primaryDiscountedPrice;
  int? secondaryPrice;
  int? secondaryDiscountedPrice;
  List<String> categories;
  List<String> tags;
  String? description;
  List<Image> images;
  String? quantity;
  int? primaryDiscountedRate;
  int? secondaryDiscountedRate;

  factory ProductModel.fromJson(Map<String, dynamic> json) => ProductModel(
        id: json["_id"],
        typeOfProduct: json["typeOfProduct"],
        name: json["name"],
        primaryPrice: (json["primaryPrice"]),
        primaryDiscountedPrice: (json["primaryDiscountedPrice"]),
        secondaryPrice: (json["secondaryPrice"]),
        secondaryDiscountedPrice: (json["secondaryDiscountedPrice"]),
        categories: List<String>.from(json["categories"].map((x) => x)),
        tags: List<String>.from(json["tags"].map((x) => x)),
        description: json["description"],
        images: List<Image>.from(json["images"].map((x) => Image.fromJson(x))),
        quantity: json["quantity"],
        primaryDiscountedRate: (json["primaryDiscountedRate"]) != null
            ? json['primaryDiscountedRate'].toInt()
            : null,
        secondaryDiscountedRate: (json["secondaryDiscountedRate"]) != null
            ? json["secondaryDiscountedRate"].toInt()
            : null,
      );

Solution

  • The mistake was response.data had the following structure

    {
      "message" : ..
      "status" : ..
      "data" : [{},{}..]
    }
    

    Accesing response.data wouldn't take me directly to data , so i had to access using response.data['data'] this solved my problem

    Final code:

    return response.data['data']
                .map((e) => ProductModel.fromJson(e))
                .toList();