Search code examples
flutterdartget

In my flutter app how to slove problem type 'List<dynamic>' is not a subtype of type 'Response<dynamic>'


dart

//model

class PostModel  {
final int?  id ;
final string? title;
final string?body;
   PostModel({ this.id, this.title , this.body});

  factory PostModel.fromJson(Map<String, dynamic> json) {
    return PostModel(id: json['id'], title: json['title'], body: json['body']);
  }

  Map<String, dynamic> toJson() {
    return {'id': id, 'title': title, 'body': body};
  }
}

//base api
abstract class BaseApiServices{

  Future<dynamic> getApi(String url);
  Future<dynamic> postApi(dynamic data ,String url);

//networkapi
class NetworkApiServices extends BaseApiServices{

  @override
  Future<dynamic> getApi(String url) async {

    if (kDebugMode) {
      print(url);

    }
    dynamic responseJson;

    try{

      final response = await http.get(Uri.parse(url),
        headers: {"Content-Type" :"application/json"},
      ).timeout(const Duration(seconds: 5));
      responseJson = returnResponse(response);
      // Check Internet
    }on SocketException{
      throw InternetException('');
    }on RequestTimeOut{
      throw RequestTimeOut('');
    }

    return responseJson;
  }
  @override
  Future<dynamic> postApi(var data ,String url) async {

    if (kDebugMode) {
      print(url);
      print(data);
    }

    dynamic responseJson;

    try{

      final response = await http.post(Uri.parse(url),

      body:data

      ).timeout(const Duration(seconds: 30));
      responseJson = returnResponse(response);
      // Check Internet
    } on SocketException{
      throw InternetException('');
    } on RequestTimeOut{
      throw RequestTimeOut('');
    }

    if (kDebugMode) {
      print(responseJson);

    }return responseJson;
  }

  dynamic returnResponse(http.Response response){
    switch(response.statusCode){

      case 200 :
          dynamic responseJson =jsonDecode(response.body);
          if (kDebugMode) {
            print(responseJson.toString());
          }
          return responseJson;
      case 400:
        dynamic responseJson =jsonDecode(response.body);
        if (kDebugMode) {
          print(responseJson.toString());
        }
        return responseJson;
      default:
        throw FetchDataExceptions('Error While Communication With service${response.statusCode}');

    }
  }


//TestRepo
class TestRepository {
  final _apiService = Get.put(NetworkApiServices());

  Future<List<PostModel>>textapi() async{
    Response response =  await _apiService.getApi(AppUrl.BASE_URL2);
    final data = response.body;
    return (data as List).map((json) => PostModel.fromJson(json)).toList();

  }
}import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:mvm_login_singup/data/response/status.dart';
import '../../../models/post.dart';
import '../../../repository/test/test_rep.dart';


class TestController extends GetxController{

  final _api = TestRepository();
  final rxRequestStatus = Status.LOADING.obs;
  final postList = <PostModel>[].obs;
  RxString error = ''.obs;
  void setRxRequestStatus(Status _value) => rxRequestStatus.value = _value;
  void setPostList(List<PostModel> _value) => postList.value = _value  ;
  void setError(String  _value) => error.value = _value;


  void postListApi(){
    _api.textapi().then((value){
      setRxRequestStatus(Status.COMPLETED);
      setPostList(value);
    }).onError((error, stackTrace) {
      if (kDebugMode) {
        print(error);
      }
      if (kDebugMode) {
        print(stackTrace);
      }
      setError(error.toString());
      setRxRequestStatus(Status.ERROR);
    });
  }
  void refreshApi(){
    setRxRequestStatus(Status.LOADING);
    _api.textapi().then((value){
      setRxRequestStatus(Status.COMPLETED);
      setPostList(value);
    }).onError((error, stackTrace) {
      if (kDebugMode) {
        print(error);
      }
      if (kDebugMode) {
        print(stackTrace);
      }
      setError(error.toString());
      setRxRequestStatus(Status.ERROR);
    });
  }

//view
class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {

 // final homeController = Get.put(HomeController());
  final testController2 = Get.put(TestController());

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
   // homeController.userListApi();
    testController2.postListApi();
  }
  @override
  Widget build(BuildContext context) {
    return   SafeArea(
        child: Scaffold(
          body: Obx((){
            switch(testController2.rxRequestStatus.value){

              case Status.LOADING:
                return const Center(child: CircularProgressIndicator());
              case Status.ERROR:
                if(testController2.error.value =='No Internet'){
                  return InterNetExceptionWidget(onPress: () {

                    testController2.refreshApi();

                  },);
                } else{
                  return  GeneralExceptionWidget(onPress: (){

                    testController2.refreshApi();

                  });
                }
              case Status.COMPLETED:
               return ListView.builder(
                // itemCount: homeController.userList.value.data!.length,
                  //  itemCount: testController2.postList.length,
                  itemCount: testController2.postList.length,


               itemBuilder: (context,index){
                     return Card(
                       child: ListTile(
                         leading: CircleAvatar(
                          // backgroundImage: NetworkImage(homeController.userList.value.data![index].avatar.toString()),
                         ),
                        // title:Text(homeController.userList.value.data![index].firstName.toString()) ,
                        // subtitle:Text(homeController.userList.value.data![index].email.toString()) ,
                         subtitle:Text(testController2.postList[index].title.toString()) ,
                       ),
                     );
                   }
               );
            }
          }),
        ));
  

Solution

  • The problem is: in your http request methods, you return a Map? but when you call those methods you want to set them as Response (it'll throw error) and after that your are also forcing Response to become a List. Please read the Dart documentation about types some more.

    The solution I propose is the following:

    abstract class BaseApiServices{
      Future<Map?> getApi(String url);
      Future<Map?> postApi(dynamic data ,String url);
    } 
    
    //networkapi
    class NetworkApiServices extends BaseApiServices{
    
      @override
      Future<Map?> getApi(String url) async {
        Map? responseJson;
    
        try{
          final response = await http.get(Uri.parse(url),
            headers: {"Content-Type" :"application/json"},
          ).timeout(const Duration(seconds: 5));
          responseJson = returnResponse(response);
          // Check Internet
        }on SocketException{
          throw InternetException('');
        }on RequestTimeOut{
          throw RequestTimeOut('');
        }
    
        return responseJson;
      }
    
    @override
      Future<dynamic> postApi(var data ,String url) async {
        Map? responseJson;
    
        try{
          final response = await http.post(Uri.parse(url),
          body:data
          ).timeout(const Duration(seconds: 30));
          responseJson = returnResponse(response);
          // Check Internet
        } on SocketException{
          throw InternetException('');
        } on RequestTimeOut{
          throw RequestTimeOut('');
        }
    
    return responseJson;
      }
    /* ... */
    //TestRepo
    class TestRepository {
      final _apiService = Get.put(NetworkApiServices());
    
      Future<List<PostModel>>textapi() async{
        Map? response = await _apiService.getApi(AppUrl.BASE_URL2);
    // print your response to see the Map key which store the list and replace it with the key used below
    return response != null ?  (response['key'] ?? []).map<PostModel>((json) => PostModel.fromJson(json)).toList()
    : [];
    
      }
    } 
    

    Make sure not to force unrelated types conversation in the rest of your code.