skip to Main Content

I’m working on an Flutter app that fetch the details of furniture from an API. I’ve to fetch 3 endpoints (/chairs, /sofas, / furnis) from the API.

So, I’ve definded _getAllFurnis() method is to make an HTTP GET request to retrieve data from three API endpoints for chairs, sofas, and furniture. If the response status code is 200 (successful), it decodes the response body into three lists of JSON objects, then converts them into lists of Furni objects and adds them to the corresponding empty List variables defined earlier. Finally, it sets _futureFurnis to a list containing these three lists of Furni objects.

Here is my entire code of the page api_shop_page.dart :

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:furnish_ar/models/Furni.dart';
import 'package:furnish_ar/pages/intro_page.dart';
import 'package:furnish_ar/pages/shop_page.dart';
import 'package:http/http.dart' as http;

class ApiShopPage extends StatefulWidget {
  const ApiShopPage({super.key});

  @override
  State<ApiShopPage> createState() => _ApiShopPageState();
}

class _ApiShopPageState extends State<ApiShopPage> {
   List<Furni> chairs = [];
   List<Furni> sofas = [];
   List<Furni> furnis = [];
   Future<List<List<Furni>>> _futureALLFurnis = [] as Future<List<List<Furni>>>;

   Future<List<List<Furni>>> _getAllFurnis() async {
       List<Map<String, dynamic>> jsonChairs = [];
       List<Map<String, dynamic>> jsonSofas = [];
       List<Map<String, dynamic>> jsonFurni = [];
       var chairUrl = "https://furnish-ar-api-s.vercel.app/chairs";
       var sofaUrl = "https://furnish-ar-api-s.vercel.app/sofas";
       var furniUrl = "https://furnish-ar-api-s.vercel.app/furnis";
       http.Response chairResponse = await http.get(Uri.parse(chairUrl));
       http.Response sofaResponse = await http.get(Uri.parse(sofaUrl));
       http.Response furniResponse = await http.get(Uri.parse(furniUrl));
       if (chairResponse.statusCode == 200 && sofaResponse.statusCode == 200 &&
           furniResponse.statusCode == 200) {
         String chairJsonData = chairResponse.body;
         String sofaJsonData = sofaResponse.body;
         String furniJsonData = furniResponse.body;

         jsonChairs = jsonDecode(chairJsonData);
         jsonSofas = jsonDecode(sofaJsonData);
         jsonFurni = jsonDecode(furniJsonData);

         for (Map<String, dynamic> index in jsonChairs) {
            chairs.add(Furni.fromJson(index));
         }   
         for (Map<String, dynamic> index in jsonSofas) {
            sofas.add(Furni.fromJson(index));
         }
         for (Map<String, dynamic> index in jsonFurni) {
            furnis.add(Furni.fromJson(index));
         }
        _futureAllFurnis = [chairs, sofas, furnis] as Future<List<List<Furni>>>;
      }
      return _futureAllFurnis;
    }

    @override
    Widget build(BuildContext context) {
       return Scaffold(
          body: FutureBuilder(
            future: _getAllFurnis(),
            builder: (context, snapshot) {
               if (snapshot.hasError) {
                   return Center(
                      child: Text(snapshot.error.toString()),
                   );  
               }

               if (snapshot.hasData && snapshot.data != null) {
                     List<List<Furni>> furnis = snapshot.data!;
                     return ShopPage(
                         chairs: furnis[0], sofas: furnis[1], furnis: furnis[2]);
               }

               return Center(
               child: CircularProgressIndicator();
        
            );
         },
      ),
    );
  }
}

The ShopPage widget is imported from a separate file and takes the lists of Furni objects as props to render a list of furniture items categorized as chairs, sofas, or other furniture items.

And I’ve Furni.fromJson() method :

factory Furni.fromJson(Map<dynamic, dynamic> json) => Furni(
    dimension: Dimension.fromJson(json["dimension"]),
    id: json["_id"],
    title: json["title"],
    description: json["description"],
    imageUrl: json["image_url"],
    modelUrl: json["model_url"],
    category: json["category"],
    price: json["price"],
    currency: json["currency"],
    rating: json["rating"]?.toDouble(),
    createdAt: DateTime.parse(json["created_at"]),
    v: json["__v"],
  );

But, when i run my application, It give me an error in the UI :

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

Can anyone please explain me why I’m getting such errors. It’ll be highly appriciated.

2

Answers


  1. My Dear friend, you should cast the result of jsonDecode() to a List<Map<String, dynamic>> by using the as operator:

    jsonChairs = jsonDecode(chairJsonData) as List<Map<String, dynamic>>;
    jsonSofas = jsonDecode(sofaJsonData) as List<Map<String, dynamic>>;
    jsonFurni = jsonDecode(furniJsonData) as List<Map<String, dynamic>>;
    

    These castings will ensure that the decoded JSON objects are the expected type that you need.

    I hope I could help you bro.

    happy coding…

    Login or Signup to reply.
  2. Consider jsonDecode output as List<dynamic> the cast to Map<String, dynamic> with each items.

    List<List<Furni>> _futureALLFurnis = <List<Furni>>[] ;
    
    Future<List<List<Furni>>> _getAllFurnis() async {
      List<dynamic> jsonChairs = <dynamic>[];
      List<dynamic> jsonSofas = <dynamic>[];
      List<dynamic> jsonFurni = <dynamic>[];
      var chairUrl = "https://furnish-ar-api-s.vercel.app/chairs";
      var sofaUrl = "https://furnish-ar-api-s.vercel.app/sofas";
      var furniUrl = "https://furnish-ar-api-s.vercel.app/furnis";
      http.Response chairResponse = await http.get(Uri.parse(chairUrl));
      http.Response sofaResponse = await http.get(Uri.parse(sofaUrl));
      http.Response furniResponse = await http.get(Uri.parse(furniUrl));
      if (chairResponse.statusCode == 200 && sofaResponse.statusCode == 200 &&
          furniResponse.statusCode == 200) {
        String chairJsonData = chairResponse.body;
        String sofaJsonData = sofaResponse.body;
        String furniJsonData = furniResponse.body;
    
        jsonChairs = jsonDecode(chairJsonData);
        jsonSofas = jsonDecode(sofaJsonData);
        jsonFurni = jsonDecode(furniJsonData);
    
        for (dynamic chair in jsonChairs) {
          chairs.add(Furni.fromJson(chair as Map<String, dynamic>));
        }
        for (dynamic sofa in jsonSofas) {
          sofas.add(Furni.fromJson(sofa as Map<String, dynamic>));
        }
        for (dynamic furni in jsonFurni) {
          furnis.add(Furni.fromJson(furni as Map<String, dynamic>));
        }
        _futureAllFurnis = [chairs, sofas, furnis];
      }
      return _futureAllFurnis;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search