Home > Software engineering >  Why doesn't parsing work? Error type 'List<dynamic>' is not a subtype of type &
Why doesn't parsing work? Error type 'List<dynamic>' is not a subtype of type &

Time:09-12

I have an error again, but of a different nature. And I can't figure out what the problem is.

The error most likely occurs when I process the response from the server. I do not quite understand, in theory, I receive an object in which there is a list of objects.

The option that does not work for me is suitable for a response from the server in the form of a single object. I thought the same should work with an object, inside which there is a list of objects. I'd like a slightly more detailed answer on this, if possible. Thank you! Code below -

response from server - response from server models -

class CartModel extends CartEntity {
  const CartModel({
    required basket,
    required delivery,
    required idCart,
    required total
}) : super (
    basket: basket,
    delivery: delivery,
    idCart: idCart,
    total: total
  );

  factory CartModel.fromJson(Map<String, dynamic> json) {
    return CartModel(
        basket: json['basket'] != null ? BasketModel.fromJson(json['basket']) : null,
        delivery: json['delivery'],
        idCart: json['id'],
        total: json['total']
    );
  }
}

class BasketModel extends Basket {
  BasketModel({id, images, price, title}) : super(id: id, images: images, price: price, title: title);

  factory BasketModel.fromJson(Map<String, dynamic> json) {
    return BasketModel(
      id: json['id'],
      images: json['images'],
      price: json['price'],
      title: json['title']
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'images': images,
      'price': price,
      'title': title
    };
  }
}

request -

Future<List<CartModel>> getAllCart() async {
    final response = await client.get(
        Uri.parse(ConfigUrl.cart),
        headers: {'Content-Type': 'application/json'}
    );
    if(response.statusCode == 200) {
      List<CartModel> result =[];
      CartModel cart = CartModel.fromJson(json.decode(response.body));
      result.add(cart);
      return result;
    } else {
      throw ServerException();
    }
  }

Also, if you change the code after checking the status to this -

final cart = json.decode(response.body);
   print(cart);
   return (cart as List).map((cart) => CartModel.fromJson(cart)).toList();

That error will become -

type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List' in type cast

And here is the response from the server in the console -

{basket: [{id: 1, images: https://www.manualspdf.ru/thumbs/products/l/1260237-samsung-galaxy-note-20-ultra.jpg, price: 1500, title: Galaxy Note 20 Ultra}, {id: 2, images: https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-13-pro-silver-select?wid=470&hei=556&fmt=jpeg&qlt=95&.v=1631652954000, price: 1800, title: iPhone 13}], delivery: Free, id: 4, total: 3300}

CodePudding user response:

json['basket'] is a List so just map its entries to convert to the object.

class CartModel extends CartEntity {
  const CartModel({
    required basket,
    required delivery,
    required idCart,
    required total
}) : super (
    basket: basket,
    delivery: delivery,
    idCart: idCart,
    total: total
  );

  factory CartModel.fromJson(Map<String, dynamic> json) {
    return CartModel(
        // Here
        basket: json['basket'] != null
          ? (json['basket'] as List<dynamic>)
              .map((json) => BasketModel.fromJson(json)).toList()
          : null;
        delivery: json['delivery'],
        idCart: json['id'],
        total: json['total']
    );
  }
}

CodePudding user response:

Because your BasketModel expecting Map<String,dynamic> and Firebase sending List.

Try this Basket Model value:

class BasketModel {
  List<Basket>? basket;

  BasketModel({this.basket});

  BasketModel.fromJson(Map<String, dynamic> json) {
    if (json['basket'] != null) {
      basket = <Basket>[];
      json['basket'].forEach((v) {
        basket!.add(new Basket.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.basket != null) {
      data['basket'] = this.basket!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Basket {
  int? id;
  String? image;
  int? price;
  String? title;

  Basket({this.id, this.image, this.price, this.title});

  Basket.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    image = json['image'];
    price = json['price'];
    title = json['title'];
  }

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