title: Type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
body: <p>I'm developing a flutter application that depends on API REST calls.The Response from the API is a bit complex.
  I can see the response from the log when calling my API (e.g : api/products) :
  But i have this Error :<br> <br> type 'List&lt; dynamic >' is not a subtype of type 'Map&lt; String, dynamic >'<br><br>
  I've seen all the questions/answers on the internet without any result.
  I've tried with a simple RestAPI like : <a href="https://my-json-server.typicode.com/typicode/demo/posts" rel="nofollow noreferrer">https://my-json-server.typicode.com/typicode/demo/posts</a> and it works.
  but it doesn't in my case
  API Response Example : </p>
  
  <pre><code>[
     {
        "id":1,
        "tenant":{
           "id":1,
           "code":"company",
           "name":"company"
        },
        "type":{
           "code":"activity",
           "name":"Activité"
        },
        "subType":{
           "code":"ticket",
           "name":"Ticket"
        },
        "inventoryType":{
           "code":"external_source",
           "name":"Source externe"
        },
        "externalReference":"CAL6970",
        "externalSystem":{
           "code":"koedia",
           "name":"Koedia"
        },
        "active":true,
        "durationDays":12,
        "durationNights":14,
        "durationHours":9,
        "durationMinutes":10,
        "supplier":{
           "id":1,
           "tenant":{
              "id":1,
              "code":"company",
              "name":"company"
           },
           "name":"Jancarthier"
        },
        "group":null,
        "subGroup":null,
        "name":"Hôtel Koulnoué Village",
        "translations":[
           {
              "id":1,
              "name":"Hôtel Koulnoué Village",
              "locale":"fr"
           },
           {
              "id":24,
              "name":"Hôtel Koulnoué Village",
              "locale":"en"
           }
        ],
        "vatPercentage":"0.00",
        "longitude":null,
        "latitude":null,
        "departureTime":null,
        "arrivalTime":null,
        "arrivalDayPlus":1,
        "stars":4,
        "localities":[
           {
              "id":41,
              "locality":{
                 "id":34,
                 "code":"ARM",
                 "name":"Armenia"
              },
              "role":{
                 "code":"stop",
                 "name":"Escale"
              }
           },
           {
              "id":49,
              "locality":{
                 "id":55,
                 "code":"hossegor",
                 "name":"Hossegor"
              },
              "role":{
                 "code":"drop_off",
                 "name":"Retour"
              }
           },
           {
              "id":50,
              "locality":{
                 "id":55,
                 "code":"hossegor",
                 "name":"Hossegor"
              },
              "role":{
                 "code":"localisation",
                 "name":"Localisation"
              }
           }
        ]
     }
  ]
  </code></pre>
  
  <p>StackTrace  : </p>
  
  <pre><code>I/flutter ( 2865): type 'List&lt;dynamic&gt;' is not a subtype of type 'Map&lt;String, dynamic&gt;'
  
  </code></pre>
  
  <p><strong>[Updated]</strong> : return ProductsResponse.fromJson(response) instead of response 
  ProductsRespository :</p>
  
  <pre><code>import 'dart:async';
  import 'package:day_experience/models/product/ProductResponse.dart';
  import 'package:day_experience/networking/ApiProvider.dart';
  
  class ProductRepository {
    ApiProvider _provider =  ApiProvider();
  
    Future&lt;ProductsResponse&gt; fetchProducts() async {
  
        final response = await _provider.getFromApi("products");
        // here line 11 where exception is thrown
        return ProductsResponse.fromJson(response);
    }
  
  
  }
  </code></pre>
  
  <p>ProductsBloc : </p>
  
  <pre><code>import 'dart:async';
  
  import 'package:day_experience/models/product/ProductResponse.dart';
  
  import 'package:day_experience/networking/Response.dart';
  import 'package:day_experience/repository/ProductRepository.dart';
  
  
  class ProductBloc {
    ProductRepository _productRepository;
    StreamController _productListController;
    bool _isStreaming;
    StreamSink&lt;Response&lt;ProductsResponse&gt;&gt; get productListSink =&gt;
        _productListController.sink;
  
  
    Stream&lt;Response&lt;ProductsResponse&gt;&gt; get productListStream =&gt;
        _productListController.stream;
  
    ProductBloc() {
      _productListController = StreamController&lt;Response&lt;ProductsResponse&gt;&gt;();
      _productRepository = ProductRepository();
      _isStreaming = true;
      fetchProducts();
  
    }
  
    fetchProducts() async {
      productListSink.add(Response.loading('Getting Products.'));
      try {
       ProductsResponse productsResponse =
        await _productRepository.fetchProducts();
       if (_isStreaming) productListSink.add(Response.completed(productsResponse));
      } catch (e) {
        if (_isStreaming) productListSink.add(Response.error(e.toString()));
        print(e);
      }
    }
  
    dispose() {
      _isStreaming = false;
      _productListController?.close();
    }
  }
  </code></pre>
  
  <p>Response : </p>
  
  <pre><code>class Response&lt;T&gt; {
    Status status;
    T data;
    String message;
  
    Response.loading(this.message) : status = Status.LOADING;
    Response.completed(this.data) : status = Status.COMPLETED;
    Response.error(this.message) : status = Status.ERROR;
  
    @override
    String toString() {
      return "Status : $status \n Message : $message \n Data : $data";
    }
  }
  
  enum Status { LOADING, COMPLETED, ERROR }
  </code></pre>
  
  <p>ApiProvider : </p>
  
  <pre><code>import 'package:day_experience/networking/CustomException.dart';
  import 'package:http/http.dart' as http;
  import 'dart:io';
  import 'dart:convert';
  import 'dart:async';
  
  class ApiProvider {
  
    final String _baseApiUrl = "URL_API/";
  
    Future&lt;dynamic&gt; getFromApi(String url) async {
      var responseJson;
      try {
        final response = await http.get(Uri.encodeFull(_baseApiUrl + url),headers:{"Accept":"application/json"} );
        print(response);
        responseJson = _response(response);
      } on SocketException {
        throw FetchDataException('No Internet connection');
      }
      return responseJson;
    }
  
    dynamic _response(http.Response response) {
      switch (response.statusCode) {
        case 200:
          var responseJson = json.decode(response.body);
  
          print(responseJson);
          return responseJson;
        case 400:
          throw BadRequestException(response.body.toString());
        case 401:
  
        case 403:
          throw UnauthorisedException(response.body.toString());
        case 500:
  
        default:
          throw FetchDataException(
              'Error occured while Communication with Server with StatusCode : ${response.statusCode}');
      }
    }
  }
  </code></pre>
  
  <p>Model : ProductResponses</p>
  
  <pre><code>import 'ExternalSystem.dart';
  import './InventoryType.dart';
  import './Localities.dart';
  import 'SubType.dart';
  import 'Supplier.dart';
  import 'Tenant.dart';
  import './Translation.dart';
  import './Type.dart';
  
  class ProductsResponse {
      final int id;
      final Tenant tenant;
      final Type type;
      final SubType subType;
      final InventoryType inventoryType;
      final String externalReference;
      final ExternalSystem externalSystem;
      final bool active;
      final int durationDays;
      final int durationNights;
      final int durationHours;
      final int durationMinutes;
      final Supplier supplier;
      final String name;
      final List&lt;Translation&gt; translations;
      final String vatPercentage;
      final int arrivalDayPlus;
      final int stars;
      final List&lt;Localities&gt; localities;
      final String group;
      final String subGroup;
      final double longitude;
      final double latitude;
      final String departureTime;
      final String arrivalTime;
  
      ProductsResponse({this.id, this.tenant , this.type, this.subType, this.inventoryType, this.externalReference, this.externalSystem, this.active, this.durationDays, this.durationNights, this.durationHours, this.durationMinutes, this.supplier, this.name, this.translations, this.vatPercentage, this.arrivalDayPlus, this.stars, this.localities, this.group, this.subGroup, this.longitude, this.latitude, this.departureTime, this.arrivalTime});
  
      factory ProductsResponse.fromJson(Map&lt;String, dynamic&gt; json) {
          return ProductsResponse(
              id: json['id'],
              tenant: json['tenant'] != null ? Tenant.fromJson(json['tenant']) : null,
              type: json['type'] != null ? Type.fromJson(json['type']) : null,
              subType: json['subType'] != null ? SubType.fromJson(json['subType']) : null,
              inventoryType: json['inventoryType'] != null ? InventoryType.fromJson(json['inventoryType']) : null,
              externalReference: json['externalReference'],
              externalSystem: json['externalSystem'] != null ? ExternalSystem.fromJson(json['externalSystem']) : null,
              active: json['active']?json['active']:null,
              durationDays: json['durationDays']?json['durationDays']:null,
              durationNights: json['durationNights']?json['durationNights']:null,
              durationHours: json['durationHours']?json['durationHours']:null,
              durationMinutes: json['durationMinutes']?json['durationMinutes']:null,
              supplier: json['supplier'] != null ? Supplier.fromJson(json['supplier']) : null,
              name: json['name']?json['name']:null,
              translations: json['translations'] != null ? (json['translations'] as List).map((i) =&gt; Translation.fromJson(i)).toList() : null,
              vatPercentage: json['vatPercentage']?json['vatPercentage']:null,
              arrivalDayPlus: json['arrivalDayPlus']?json['arrivalDayPlus']:null,
              stars: json['stars']?json['stars']:null,
              localities: json['localities'] != null ? (json['localities'] as List).map((i) =&gt; Localities.fromJson(i)).toList() : null,
              group: json['group'] != null ? json['group'] : null,
              subGroup: json['subGroup'] != null ? json['subGroup'] : null,
              longitude: json['longitude'] != null ? json['longitude'] : null,
              latitude: json['latitude'] != null ? json['latitude'] : null,
              departureTime: json['departureTime'] != null ? json['departureTime'] : null,
              arrivalTime: json['arrivalTime'] != null ? json['arrivalTime'] : null,
          );
      }
  
      Map&lt;String, dynamic&gt; toJson() {
          final Map&lt;String, dynamic&gt; data = new Map&lt;String, dynamic&gt;();
          data['id'] = this.id;
          data['externalReference'] = this.externalReference;
          data['active'] = this.active;
          data['durationDays'] = this.durationDays;
          data['durationNights'] = this.durationNights;
          data['durationHours'] = this.durationHours;
          data['durationMinutes'] = this.durationMinutes;
          data['name'] = this.name;
          data['vatPercentage'] = this.vatPercentage;
          data['arrivalDayPlus'] = this.arrivalDayPlus;
          data['stars'] = this.stars;
          if (this.tenant != null) {
              data['tenant'] = this.tenant.toJson();
          }
         if (this.type != null) {
              data['type'] = this.type.toJson();
          }
          if (this.subType != null) {
              data['subType'] = this.subType.toJson();
          }
          if (this.inventoryType != null) {
              data['inventoryType'] = this.inventoryType.toJson();
          }
          if (this.externalSystem != null) {
              data['externalSystem'] = this.externalSystem.toJson();
          }
          if (this.supplier != null) {
              data['supplier'] = this.supplier.toJson();
          }
          if (this.translations != null) {
              data['translations'] = this.translations.map((v) =&gt; v.toJson()).toList();
          }
          if (this.localities != null) {
              data['localities'] = this.localities.map((v) =&gt; v.toJson()).toList();
          }
          if (this.group != null) {
              data['group'] = this.group;
          }
          if (this.subGroup != null) {
              data['subGroup'] = this.subGroup;
          }
          if (this.longitude != null) {
              data['longitude'] = this.longitude;
          }
          if (this.latitude != null) {
              data['latitude'] = this.latitude;
          }
          if (this.departureTime != null) {
              data['departureTime'] = this.departureTime;
          }
          if (this.arrivalTime != null) {
              data['arrivalTime'] = this.arrivalTime;
          }
        print(data);
  
          return data;
      }
  }
  </code></pre>
  
  <p><strong>[Updated]</strong> : removed ProductsRepository (should only access via bloc)<br>
  ProductView</p>
  
  <pre><code>import 'package:day_experience/blocs/ProductBloc.dart';
  import 'package:day_experience/models/product/ProductResponse.dart';
  import 'package:day_experience/networking/Response.dart';
  import 'package:day_experience/repository/ProductRepository.dart';
  import 'package:day_experience/view/widget/Loading.dart';
  import 'package:day_experience/view/widget/ProductList.dart';
  import 'package:flutter/material.dart';
  import 'package:day_experience/view/widget/Error.dart';
  
  
  class ProductView extends StatefulWidget {
   @override
   _ProductViewState createState() =&gt; _ProductViewState();
  }
  
  class _ProductViewState extends State&lt;ProductView&gt; {
   ProductBloc _bloc = new ProductBloc();
  
   @override
   void initState() {
     super.initState();
     _bloc.fetchProducts();
   }
  
   @override
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
         elevation: 0.0,
         automaticallyImplyLeading: false,
         title: Text('Products',
             style: TextStyle(color: Colors.white, fontSize: 20)),
         backgroundColor: Color(0xFF333333),
       ),
       backgroundColor: Color(0xFF333333),
       body: RefreshIndicator(
         onRefresh: () =&gt; _bloc.fetchProducts(),
         child: StreamBuilder&lt;Response&lt;ProductsResponse&gt;&gt;(
           stream: _bloc.productListStream,
           builder: (context, snapshot) {
             if (snapshot.hasData) {
               switch (snapshot.data.status) {
                 case Status.LOADING:
                   return Loading(loadingMessage: snapshot.data.message);
                   break;
                 case Status.COMPLETED:
                   return ProductList(productList:snapshot.data.data);
                   break;
                 case Status.ERROR:
                   return Error(
                     errorMessage: snapshot.data.message,
                     onRetryPressed: () =&gt; _bloc.fetchProducts(),
                   );
                   break;
               }
             }
             return Container();
           },
         ),
       ),
     );
   }
  
  
  }
  
  
  </code></pre>
  
  <p>Tenant Example same logic for others(Translation,Type,SubType..)</p>
  
  <pre><code>class Tenant {
     final int id;
     final String code;
     final String name;
  
     Tenant({this.id, this.code, this.name});
  
     factory Tenant.fromJson(Map&lt;String, dynamic&gt; json) {
         return Tenant(
             id: json['id'], 
             code: json['code'], 
             name: json['name'], 
         );
     }
  
     Map&lt;String, dynamic&gt; toJson() {
         final Map&lt;String, dynamic&gt; data = new Map&lt;String, dynamic&gt;();
         data['id'] = this.id;
         data['code'] = this.code;
         data['name'] = this.name;
         return data;
     }
  }
  </code></pre>