Search code examples
flutterflutter-futurebuilder

Expected a value of type 'ProductList', but got one of type '_Future<ProductList>'


I am trying to consume a rest api data returning a list of maps each map contain product details, so i code classes for product as well as productList with fromJsom method implemented, then i am trying to dispaly thoes products in my flutter app with list.generate but got the error "Expected a value of type 'ProductList', but got one of type '_Future'"

here is the function responsible of api call, its return a Future of type ProductList:

Future<ProductList> loadProductsByIdService(_serviceid) async {

  var datamap = {'service_id': _serviceid};
  var data = json.encode(datamap);
  ProductList products;

  final response = await http.post(Uri.parse(PRODUCTS),
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/x-www-form-urlencoded"
      },
      body: data,
      encoding: Encoding.getByName("utf-8"));

  if (response.body.isNotEmpty) {

    if (response.statusCode == 200) {
      products = ProductList.fromJson(json.decode(response.body));
     
    }

  } else {
    throw Exception('echec de chargement des produits');
  }

  return products;
}

and here the class responsible of displaying products

class PopularProducts extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var products = loadProductsByIdService(1) as ProductList;

    return Column(
      children: [
        Padding(
          padding:
              EdgeInsets.symmetric(horizontal: getPropotionalScreenWidth(20)),
          child: SectionTitle(title: "Produits à la Une", press: () {}),
        ),
        SizedBox(height: getPropotionalScreenWidth(20)),
        SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(
            children: [
              ...List.generate(
                products.products.length,
                (index) {
                  return ProductCard(product: products.products[index]);
                },
              ),
              SizedBox(width: getPropotionalScreenWidth(20)),
            ],
          ),
        )
      ],
    );
  }
}

also i am getting this error alongside: "errors.dart:187 Uncaught (in promise) Error: FormatException: SyntaxError: Unexpected end of JSON input"


Solution

  • You are trying to paint the data before you get it. You must wrap your column in a futureBuilder to wait for that data.

    return FutureBuilder<ProductList>(
          future: loadProductsByIdService(1),
          builder: (context, snapShot) {
            if (snapshot.hasData) {
              return Column(
                children: [
                  Padding(
                    padding:
                        EdgeInsets.symmetric(horizontal: getPropotionalScreenWidth(20)),
                    child: SectionTitle(title: "Produits à la Une", press: () {}),
                  ),
                  SizedBox(height: getPropotionalScreenWidth(20)),
                  SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: Row(
                      children: [
                        ...List.generate(
                          snapShot.products.length,
                          (index) {
                            return ProductCard(product: snapShot.products[index]);
                          },
                        ),
                        SizedBox(width: getPropotionalScreenWidth(20)),
                      ],
                    ),
                  )
                ],
              ); 
            } else {
              return SizedBox();
            }
          },
        );