Home > Net >  When i am trying to fetch api this error : "type 'List<dynamic>' is not a subty
When i am trying to fetch api this error : "type 'List<dynamic>' is not a subty

Time:11-28

I am trying to create a API request in Flutter but I'm getting following error as response

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

I am trying to create first API and kindly let me know if the approach is fine here is my code:

Future<Welcome> fetchProduct() async {
  final response = await http.get(Uri.parse(
      'https://api.azabazar.com/api/all-products/?fbclid=IwAR0v4BAB_gFTcpU7Jjqg_t0MnUkUxq8sWPgLj1BHrmOOq_Nd132mz9F8iSU'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Welcome.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

class model:

class Welcome {
  final String title;
  final DateTime date;
  final String image;
  final String description;
  final int category;
  final int price;

  Welcome({
    required this.title,
    required this.date,
    required this.image,
    required this.description,
    required this.category,
    required this.price,
  });

  factory Welcome.fromJson(Map<String, dynamic> json) {
    return Welcome(
      title: json["title"],
      date: DateTime.parse(json["date"]),
      image: json["image"],
      description: json["description"],
      category: json["category"],
      price: json["price"],
    );
  }

Here is my sample API

[
    {
        "title": "iphone 6s",
        "date": "2021-07-11T15:51:35.289193Z",
        "image": "/media/products/IMG_20210227_002515.jpg",
        "description": "iphone 6s \r\nDisplay: 4.7\"\r\nRam-2GB\r\nROM-64GB",
        "category": 2,
        "price": 10000
    },
    {
        "title": "iphone 6s again",
        "date": "2021-07-11T15:52:22.457555Z",
        "image": "/media/products/IMG_20210227_002515_jtKsLrL.jpg",
        "description": "iphone 6s \r\nscru chara phone",
        "category": 2,
        "price": 5500
    },
    {
        "title": "pegion",
        "date": "2021-08-09T16:37:18.410878Z",
        "image": "/media/products/download_gQUBVZK.png",
        "description": "this is a pegion, cinese owal",
        "category": 3,
        "price": 3000
    },
    {
        "title": "pulser",
        "date": "2021-08-25T06:14:58.402376Z",
        "image": "/media/products/50340732_332072787517362_7912562101313339392_n.jpg",
        "description": "bajaj pulser ,fbhfubfj",
        "category": 4,
        "price": 100000
    }
]

I've also used futureBuilder :

  late Future<Welcome> futureProduct;
  @override
  void initState() {
    super.initState();
    futureProduct = fetchProduct();
  }

CodePudding user response:

It is because your API does not return a single Welcome item but rather multiple Welcome items.

You can adjust the fetchProduct method to return a List<Welcome>:

Future<List<Welcome>> fetchProducts() async {
  final response = await http.get(Uri.parse(
      'https://api.azabazar.com/api/all-products/?fbclid=IwAR0v4BAB_gFTcpU7Jjqg_t0MnUkUxq8sWPgLj1BHrmOOq_Nd132mz9F8iSU'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return [
      for (final item in jsonDecode(response.body)) Welcome.fromJson(item),
    ];
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

CodePudding user response:

you problem is return Welcome.fromJson(jsonDecode(response.body)); in this line because you are receiving a list response from api but you are parsing with Map so, do following changes,

  1. update class with following
//add this line
List<Welcome> welcomeFromJson(String str) => List<Welcome>.from(json.decode(str).map((x) => Welcome.fromJson(x)));

//add this line
String welcomeToJson(List<Welcome> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Welcome {
    Welcome({
        required this.title,
        required this.date,
        required this.image,
        required this.description,
        required this.category,
        required this.price,
    });

    final String title;
    final DateTime date;
    final String image;
    final String description;
    final int category;
    final int price;

    factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
        title: json["title"],
        date: DateTime.parse(json["date"]),
        image: json["image"],
        description: json["description"],
        category: json["category"],
        price: json["price"],
    );

    Map<String, dynamic> toJson() => {
        "title": title,
        "date": date.toIso8601String(),
        "image": image,
        "description": description,
        "category": category,
        "price": price,
    };
}

  1. use this function where you parse string
Future<Welcome> fetchProduct() async {
  final response = await http.get(Uri.parse(
      'https://api.azabazar.com/api/all-products/?fbclid=IwAR0v4BAB_gFTcpU7Jjqg_t0MnUkUxq8sWPgLj1BHrmOOq_Nd132mz9F8iSU'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return welcomeFromJson(response.body);<-- change in this line
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}
  • Related