skip to Main Content

Get an Error: type String is not a subtype of type Map String, dynamic

import 'package:ajooyo/features/products/models/product_model.dart';

class CartItem {
  final Product product;
  final int quantity;
  final String id;

  CartItem({
    required this.product,
    required this.quantity,
    required this.id,
  });

  factory CartItem.fromJson(Map<String, dynamic> json) {
    return CartItem(
      product: Product.fromJson(json['product']),
      quantity: json['quantity'],
      id: json['_id'],
    );
  }
}

Cart model

import 'package:ajooyo/features/products/models/product_cart_item_model.dart';

class Cart {
  final String id;
  final String userId;
  final List<CartItem> items;

  Cart({
    required this.id,
    required this.userId,
    required this.items,
  });

  factory Cart.fromJson(Map<String, dynamic> json) {
    return Cart(
      id: json['_id'] as String,
      userId: json['user'] as String,
      items: (json['items'] as List)
          .map((item) => CartItem.fromJson(item as Map<String, 
           dynamic>)).toList(),
    );
  }
}


Here is the json file coming from the backend

{
    "updatedCart": {
        "_id": "66442f4",
        "user": "6628996ba",
        "items": [
            {
                "product": {
                    "_id": "66496e7e",
                    "user": "6696ba",
                    "vendor": "66311944",
                    "productName": "Yemlays Men's Fashion Comfortable Hoodie-black",
                    "productBrandName": "Yemlays",
                    "productPrice": "24,360",
                    "productDescription": "Welcome to our shop.",
                    "productDaysOfDelivery": "3",
                    "productType": "Clothing",
                    "productSize": "Regular",
                    "productQuantity": "",
                    "productImages": [
                        {
                            "productUrl": "https://_image/td3tadqj2n52vpelxntk.jpg",
                            "_id": "6640c8b824675c8aaa196e7f"
                        }
                    ],
                    "productAvailability": true,
                    "productStatus": "active",
                    "createdAt": "2024-05-12T13:48:40.612Z",
                    "updatedAt": "2024-05-12T13:48:40.612Z",
                    "__v": 0
                },
                "quantity": 2,
                "_id": "664454addc21f61eb83252f7"
            },
            {
                "product": {
                    "_id": "66403",
                    "user": "66ba",
                    "vendor": "66310e944",
                    "productName": "Yemlays Martin Boots Men's Tooling All-match High-top Shoes-beige",
                    "productBrandName": "Yemlays",
                    "productPrice": "9,467",
                    "productDescription": "This pair in addition to.",
                    "productDaysOfDelivery": "3",
                    "productType": "Foot Wares",
                    "productSize": "44",
                    "productQuantity": "",
                    "productImages": [
                        {
                            "productUrl": "https://t_image/xalew0pxva25ly49xb1w.jpg",
                            "_id": "6640c86224675c8aaa196e74"
                        },
                        {
                            "productUrl": "https://r9w.jpg",
                            "_id": "6640c86224675c8aaa196e75"
                        },
                        {
                            "productUrl": "https://re.jpg",
                            "_id": "6640c86224675c8aaa196e76"
                        },
                        {
                            "productUrl": "https://repg",
                            "_id": "6640c86224675c8aaa196e77"
                        }
                    ],
                    "productAvailability": true,
                    "productStatus": "active",
                    "createdAt": "2024-05-12T13:47:14.889Z",
                    "updatedAt": "2024-05-12T13:47:14.889Z",
                    "__v": 0
                },
                "quantity": 1,
                "_id": "664455b9dc21f61eb8325313"
            }
        ],
        "__v": 1
    }
}

I expect it to map through the data, but i keep on getting the data fromJson
But in the below code it printed Response data is a Map; which mean the api data is a Map data,
Also for this print("Response type: ${response.data.runtimeType}");, it printed Response type: _Map<String, dynamic>

So i seriously don’t know where the error is coming from…

Future<Cart?> addProductToCart(String productId, int quantity) async {
    try {
      const endpoint = "user/add_product_cart";
      final response = await apiProvider.post(endpoint, data: {
        'productId': productId,
        'quantity': quantity,
      });

      // Debugging information
      print("Response type: ${response.data.runtimeType}");
      print("Response data: ${response.data}");

      if (response.data is Map<String, dynamic>) {
        print("Response data is a Map");

        final updatedCartData =
            response.data['updatedCart'] as Map<String, dynamic>;
        print("updatedCart data type: ${updatedCartData.runtimeType}");

        return Cart.fromJson(updatedCartData);
      } else {
        print("Response data is not a Map");
        throw Exception('Unexpected response format');
      }
    } catch (e) {
      print("Error: $e");
      print('Error occures here');
      rethrow;
      // throw Exception('Failed to add product to cart: $e');
    }
  }

2

Answers


  1. I suppose your model is not fitting json data. You can convert your json data to class simply with this website: https://javiercbk.github.io/json_to_dart/

    I convert your json data to model and result like this:

    class CartItem {
      UpdatedCart? updatedCart;
    
      CartItem({this.updatedCart});
    
      CartItem.fromJson(Map<String, dynamic> json) {
        updatedCart = json['updatedCart'] != null
            ? UpdatedCart.fromJson(json['updatedCart'])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        if (updatedCart != null) {
          data['updatedCart'] = updatedCart!.toJson();
        }
        return data;
      }
    }
    
    class UpdatedCart {
      String? sId;
      String? user;
      List<Items>? items;
      int? iV;
    
      UpdatedCart({this.sId, this.user, this.items, this.iV});
    
      UpdatedCart.fromJson(Map<String, dynamic> json) {
        sId = json['_id'];
        user = json['user'];
        if (json['items'] != null) {
          items = <Items>[];
          json['items'].forEach((v) {
            items!.add(Items.fromJson(v));
          });
        }
        iV = json['__v'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data['_id'] = sId;
        data['user'] = user;
        if (items != null) {
          data['items'] = items!.map((v) => v.toJson()).toList();
        }
        data['__v'] = iV;
        return data;
      }
    }
    
    class Items {
      Product? product;
      int? quantity;
      String? sId;
    
      Items({this.product, this.quantity, this.sId});
    
      Items.fromJson(Map<String, dynamic> json) {
        product =
            json['product'] != null ? Product.fromJson(json['product']) : null;
        quantity = json['quantity'];
        sId = json['_id'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        if (product != null) {
          data['product'] = product!.toJson();
        }
        data['quantity'] = quantity;
        data['_id'] = sId;
        return data;
      }
    }
    
    class Product {
      String? sId;
      String? user;
      String? vendor;
      String? productName;
      String? productBrandName;
      String? productPrice;
      String? productDescription;
      String? productDaysOfDelivery;
      String? productType;
      String? productSize;
      String? productQuantity;
      List<ProductImages>? productImages;
      bool? productAvailability;
      String? productStatus;
      String? createdAt;
      String? updatedAt;
      int? iV;
    
      Product(
          {this.sId,
          this.user,
          this.vendor,
          this.productName,
          this.productBrandName,
          this.productPrice,
          this.productDescription,
          this.productDaysOfDelivery,
          this.productType,
          this.productSize,
          this.productQuantity,
          this.productImages,
          this.productAvailability,
          this.productStatus,
          this.createdAt,
          this.updatedAt,
          this.iV});
    
      Product.fromJson(Map<String, dynamic> json) {
        sId = json['_id'];
        user = json['user'];
        vendor = json['vendor'];
        productName = json['productName'];
        productBrandName = json['productBrandName'];
        productPrice = json['productPrice'];
        productDescription = json['productDescription'];
        productDaysOfDelivery = json['productDaysOfDelivery'];
        productType = json['productType'];
        productSize = json['productSize'];
        productQuantity = json['productQuantity'];
        if (json['productImages'] != null) {
          productImages = <ProductImages>[];
          json['productImages'].forEach((v) {
            productImages!.add(ProductImages.fromJson(v));
          });
        }
        productAvailability = json['productAvailability'];
        productStatus = json['productStatus'];
        createdAt = json['createdAt'];
        updatedAt = json['updatedAt'];
        iV = json['__v'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data['_id'] = sId;
        data['user'] = user;
        data['vendor'] = vendor;
        data['productName'] = productName;
        data['productBrandName'] = productBrandName;
        data['productPrice'] = productPrice;
        data['productDescription'] = productDescription;
        data['productDaysOfDelivery'] = productDaysOfDelivery;
        data['productType'] = productType;
        data['productSize'] = productSize;
        data['productQuantity'] = productQuantity;
        if (productImages != null) {
          data['productImages'] = productImages!.map((v) => v.toJson()).toList();
        }
        data['productAvailability'] = productAvailability;
        data['productStatus'] = productStatus;
        data['createdAt'] = createdAt;
        data['updatedAt'] = updatedAt;
        data['__v'] = iV;
        return data;
      }
    }
    
    class ProductImages {
      String? productUrl;
      String? sId;
    
      ProductImages({this.productUrl, this.sId});
    
      ProductImages.fromJson(Map<String, dynamic> json) {
        productUrl = json['productUrl'];
        sId = json['_id'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data['productUrl'] = productUrl;
        data['_id'] = sId;
        return data;
      }
    }
    
    
    Login or Signup to reply.
  2. I expect it to map through the data, but i keep on getting the data
    fromJson But in the below code it printed Response data is a Map;
    which mean the api data is a Map data…

    Correct, the whole response is a map.

    However, the error of type String is not a subtype of type Map<String, dynamic> can be unrelated to the main response, it can be one of the sub-types of the main response, such as the Product or any sub-type of it. Somewhere, an object (map) in the response is getting deserialized as a string instead.

    A good way to resolve such an issue is to make a new model (sub-type) for each object in your response:

    class ResponseModel {
      UpdatedCart? updatedCart;
    
      ResponseModel({this.updatedCart});
    
      ResponseModel.fromJson(Map<String, dynamic> json) {
        updatedCart = json['updatedCart'] != null
            ? UpdatedCart.fromJson(json['updatedCart'])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        if (updatedCart != null) {
          data['updatedCart'] = updatedCart!.toJson();
        }
        return data;
      }
    }
    
    class UpdatedCart {
      String? sId;
      String? user;
      List<Items>? items;
      int? iV;
    
      UpdatedCart({this.sId, this.user, this.items, this.iV});
    
      UpdatedCart.fromJson(Map<String, dynamic> json) {
        sId = json['_id'];
        user = json['user'];
        if (json['items'] != null) {
          items = <Items>[];
          json['items'].forEach((v) {
            items!.add(Items.fromJson(v));
          });
        }
        iV = json['__v'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data['_id'] = sId;
        data['user'] = user;
        if (items != null) {
          data['items'] = items!.map((v) => v.toJson()).toList();
        }
        data['__v'] = iV;
        return data;
      }
    }
    
    class Items {
      Product? product;
      int? quantity;
      String? sId;
    
      Items({this.product, this.quantity, this.sId});
    
      Items.fromJson(Map<String, dynamic> json) {
        product =
            json['product'] != null ? Product.fromJson(json['product']) : null;
        quantity = json['quantity'];
        sId = json['_id'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        if (product != null) {
          data['product'] = product!.toJson();
        }
        data['quantity'] = quantity;
        data['_id'] = sId;
        return data;
      }
    }
    
    class Product {
      String? sId;
      String? user;
      String? vendor;
      String? productName;
      String? productBrandName;
      String? productPrice;
      String? productDescription;
      String? productDaysOfDelivery;
      String? productType;
      String? productSize;
      String? productQuantity;
      List<ProductImages>? productImages;
      bool? productAvailability;
      String? productStatus;
      String? createdAt;
      String? updatedAt;
      int? iV;
    
      Product(
          {this.sId,
          this.user,
          this.vendor,
          this.productName,
          this.productBrandName,
          this.productPrice,
          this.productDescription,
          this.productDaysOfDelivery,
          this.productType,
          this.productSize,
          this.productQuantity,
          this.productImages,
          this.productAvailability,
          this.productStatus,
          this.createdAt,
          this.updatedAt,
          this.iV});
    
      Product.fromJson(Map<String, dynamic> json) {
        sId = json['_id'];
        user = json['user'];
        vendor = json['vendor'];
        productName = json['productName'];
        productBrandName = json['productBrandName'];
        productPrice = json['productPrice'];
        productDescription = json['productDescription'];
        productDaysOfDelivery = json['productDaysOfDelivery'];
        productType = json['productType'];
        productSize = json['productSize'];
        productQuantity = json['productQuantity'];
        if (json['productImages'] != null) {
          productImages = <ProductImages>[];
          json['productImages'].forEach((v) {
            productImages!.add(ProductImages.fromJson(v));
          });
        }
        productAvailability = json['productAvailability'];
        productStatus = json['productStatus'];
        createdAt = json['createdAt'];
        updatedAt = json['updatedAt'];
        iV = json['__v'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data['_id'] = sId;
        data['user'] = user;
        data['vendor'] = vendor;
        data['productName'] = productName;
        data['productBrandName'] = productBrandName;
        data['productPrice'] = productPrice;
        data['productDescription'] = productDescription;
        data['productDaysOfDelivery'] = productDaysOfDelivery;
        data['productType'] = productType;
        data['productSize'] = productSize;
        data['productQuantity'] = productQuantity;
        if (productImages != null) {
          data['productImages'] =
              productImages!.map((v) => v.toJson()).toList();
        }
        data['productAvailability'] = productAvailability;
        data['productStatus'] = productStatus;
        data['createdAt'] = createdAt;
        data['updatedAt'] = updatedAt;
        data['__v'] = iV;
        return data;
      }
    }
    
    class ProductImages {
      String? productUrl;
      String? sId;
    
      ProductImages({this.productUrl, this.sId});
    
      ProductImages.fromJson(Map<String, dynamic> json) {
        productUrl = json['productUrl'];
        sId = json['_id'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data['productUrl'] = productUrl;
        data['_id'] = sId;
        return data;
      }
    }
    

    ResponseModel is the output of parsing the whole response, which contains sub-types for each object in the response. For instance, you could access data as:

    final response = ResponseModel.fromJson(responseMap);
    
    final items = response.updatedCart?.items;
    final productBrandName = items?.first.product?.productBrandName;
    

    responseMap is simply your response. You could test it by declaring a local (mock) one instead of doing an actual endpoint request:

    const responseMap = {
        "updatedCart": {
            "_id": "66442f4",
            "user": "6628996ba",
            "items": [
                {
                    "product": {
                        "_id": "66496e7e",
                        "user": "6696ba",
                        "vendor": "66311944",
                        "productName": "Yemlays Men's Fashion Comfortable Hoodie-black",
                        "productBrandName": "Yemlays",
                        "productPrice": "24,360",
                        "productDescription": "Welcome to our shop.",
                        "productDaysOfDelivery": "3",
                        "productType": "Clothing",
                        "productSize": "Regular",
                        "productQuantity": "",
                        "productImages": [
                            {
                                "productUrl": "https://_image/td3tadqj2n52vpelxntk.jpg",
                                "_id": "6640c8b824675c8aaa196e7f"
                            }
                        ],
                        "productAvailability": true,
                        "productStatus": "active",
                        "createdAt": "2024-05-12T13:48:40.612Z",
                        "updatedAt": "2024-05-12T13:48:40.612Z",
                        "__v": 0
                    },
                    "quantity": 2,
                    "_id": "664454addc21f61eb83252f7"
                },
                {
                    "product": {
                        "_id": "66403",
                        "user": "66ba",
                        "vendor": "66310e944",
                        "productName": "Yemlays Martin Boots Men's Tooling All-match High-top Shoes-beige",
                        "productBrandName": "Yemlays",
                        "productPrice": "9,467",
                        "productDescription": "This pair in addition to.",
                        "productDaysOfDelivery": "3",
                        "productType": "Foot Wares",
                        "productSize": "44",
                        "productQuantity": "",
                        "productImages": [
                            {
                                "productUrl": "https://t_image/xalew0pxva25ly49xb1w.jpg",
                                "_id": "6640c86224675c8aaa196e74"
                            },
                            {
                                "productUrl": "https://r9w.jpg",
                                "_id": "6640c86224675c8aaa196e75"
                            },
                            {
                                "productUrl": "https://re.jpg",
                                "_id": "6640c86224675c8aaa196e76"
                            },
                            {
                                "productUrl": "https://repg",
                                "_id": "6640c86224675c8aaa196e77"
                            }
                        ],
                        "productAvailability": true,
                        "productStatus": "active",
                        "createdAt": "2024-05-12T13:47:14.889Z",
                        "updatedAt": "2024-05-12T13:47:14.889Z",
                        "__v": 0
                    },
                    "quantity": 1,
                    "_id": "664455b9dc21f61eb8325313"
                }
            ],
            "__v": 1
        }
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search