1

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

type 'List<dynamic>' 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

import 'package:flutter/material.dart';

class Product {
  final int id;
  final String title, description;
  final String images;
  final List<Color> colors;
  final double price;
  final double rating;
  final bool isFavourite, isPopular;

  Product(
      {this.id,
      this.images,
      this.colors,
      this.title,
      this.price,
      this.rating,
      this.description,
      this.isFavourite,
      this.isPopular});
  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      images: json['images'],
      title: json['title'],
      price: json['price'],
      rating: json['rating'],
      description: json['description'],
    );
  }
}


Future<Product> fetchProd() async {
  final response = await http.get('https://test.com/sampleapi.php');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Product.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 ProdList extends StatefulWidget {
  @override
  _ProdListState createState() => _ProdListState();
}

class _ProdListState extends State<ProdList> {
  Future<Product> futureProdLists;
  @override
  void initState() {
    super.initState();
    futureProdLists = fetchProd();
  
  }

 

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Padding(
        padding:
            EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)),
        child: SectionTitle(title: "Popular Products", press: () {}),
      ),
      SizedBox(height: getProportionateScreenWidth(20)),
      SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: FutureBuilder<Product>(
          future: futureProdLists,
          builder: (context, snapshot) {
            print(snapshot);
            if (snapshot.hasData) {
              return Text(snapshot.data.title);
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }

Here is my sample API

[
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  }
]

3 Answers 3

0

The thing is your api response giving you an json array of product object and you are trying to convert the array to product object that is the problem.

Now you have to iterate the json array and convert each element to Product object and store them in a list.

Replace your fetchProd method with bellow code snippet.

Future<List<Product>> fetchProd() async {
  List<Product> prodList = [];

  final response = await http.get('https://test.com/sampleapi.php');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    var jsonList = jsonDecode(response.body);
    for(var prod in jsonList){
      prodList.add(Product.fromJson(prod));
    }
    return prodList;
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

A value of type 'List<Product>' can't be returned from function 'fetchProd' because it has a return type of 'Future<Product>'.dartreturn_of_invalid_type
As @Saiful Islam its API returns JSON array not json object so that is List not Map.
I updated the code so make a try now. @vellai durai
0

try this

Future<Product> fetchProd() async {
  final response = await http.get('https://test.com/sampleapi.php');

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

Comments

0

This will work for sure. final Product product = productFromJson(jsonString);


import 'dart:convert';

List<Product> productFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));

String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Product {
    Product({
        this.id,
        this.images,
        this.title,
        this.price,
        this.description,
        this.rating,
        this.ratingCopy,
        this.isFavourite,
        this.isPopular,
    });

    String id;
    String images;
    String title;
    int price;
    String description;
    double rating;
    double ratingCopy;
    bool isFavourite;
    bool isPopular;

    factory Product.fromJson(Map<String, dynamic> json) => Product(
        id: json["id"],
        images: json["images"],
        title: json["title"],
        price: json["price"],
        description: json["description"],
        rating: json["rating"].toDouble(),
        ratingCopy: json["rating (copy)"].toDouble(),
        isFavourite: json["isFavourite"],
        isPopular: json["isPopular"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "images": images,
        "title": title,
        "price": price,
        "description": description,
        "rating": rating,
        "rating (copy)": ratingCopy,
        "isFavourite": isFavourite,
        "isPopular": isPopular,
    };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.