Home > Net >  Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<ima
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<ima

Time:04-24

I have been trying to actually get the data from firebase So the actual data is : enter image description here

How to get the imageUrl ?

My Try is :

class ProductModel {
  String? name;
  String? price;
  String? discountPrice;
  String? discountRate;
  String? category;
  String? description;
  List<imageObject>? image;

  ProductModel(
      {required this.name,
      required this.price,
      this.category,
      this.description,
      this.discountPrice,
      this.discountRate,
      this.image});

  ProductModel.fromMap(Map<String, dynamic> data) {
    
    name = data['name'];
    // image = data['imageUrls'][0]['url']; // To get single image i do this
    image = data['imageUrls']; // but this is not working 
    category = data['category'];
    description = data['Description'];
    price = data['price'];
    discountPrice = data['discountPrice'];
    discountRate = data['discountRate'];
  }
}

class imageObject {
  final String public_id;
  final String url;

  imageObject({
    required this.public_id,
    required this.url,
  });
}

It gives exception :Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<imageObject>?'

And to access the first image i am doing,

product.image![0].url,

where product is of type ProductModel

But this is not working

CodePudding user response:

You need to deserialize the imageObject json data as well. For that you need to add the factory imageObject.fromJson() constructor to your imageObject class just like you did for the ProductModel class.

Here's the code you need:

  class ProductModel {
  String? name;
  String? price;
  String? discountPrice;
  String? discountRate;
  String? category;
  String? description;
  List<imageObject>? image;

  ProductModel({
    required this.name,
    required this.price,
    this.category,
    this.description,
    this.discountPrice,
    this.discountRate,
    this.image,
  });

  factory ProductModel.fromJson(Map<String, dynamic> jsonData) => ProductModel(
        name: jsonData['name'] as String?,
        price: jsonData['price'] as String?,
        category: jsonData['category'] as String?,
        description: jsonData['Description'] as String?,
        discountPrice: jsonData['discountPrice'] as String?,
        discountRate: jsonData['discountRate'] as String?,
        
        //Have a good look here to understand how nested list of maps are deserialized

        image: (jsonData['imageUrls'] as List<dynamic>?)
            ?.map((e) => imageObject.fromJson(e as Map<String, dynamic>))
            .toList(),
      );
}

class imageObject {
  final String public_id;
  final String url;

  imageObject({
    required this.public_id,
    required this.url,
  });

  factory imageObject.fromJson(Map<String, dynamic> jsonData) => imageObject(
        public_id: jsonData['public_id'] as String,
        url: jsonData['url'] as String,
      );
}

What we did here is, take the data from imageUrls key as a List and map every individual element thru the json constructor of the imageObject method.

CodePudding user response:

You have to map the recived list to an imageObjects list.

  1. Create a fromMap constructor for your imageObject class
class imageObject {
  final String public_id;
  final String url;

  imageObject({
    required this.public_id,
    required this.url,
  });
  imageObject.fromMap(Map<String, dynamic> map) => imageObject(public_id = map['public_id'], url = map['url'] );
}
  1. Use it something like the following:
 ProductModel.fromMap(Map<String, dynamic> data) {
    
    name = data['name'];
    image = data['imageUrls'].map((map) => imageObject.fromMap(map) ); 
    category = data['category'];
    description = data['Description'];
    price = data['price'];
    discountPrice = data['discountPrice'];
    discountRate = data['discountRate'];
  }

You may need to do add some casting or do some modifications to the previous code make it work, but this is the general idea.

  • Related