skip to Main Content

I find this error and I need help resolving this error:

error: ‘_Map<String, dynamic>’ is not a subtype of type ‘List<dynamic>’

URL return JSON:

{"userId": 1,"id": 1,"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit","body": "quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto"}**

This code: API

import 'dart:convert';
import 'dart:ffi';
import 'package:http/http.dart' as http;
import '../model/user_model.dart';

String appUrl = "https://jsonplaceholder.typicode.com/posts/1";

class AppRepostry {
  Future<List<UserModel>> getApp() async {
    http.Response response = await http.get(Uri.parse(appUrl));

    if (response.statusCode == 200) {
      final List resuilt = jsonDecode(response.body);

      return resuilt.map((e) => UserModel.fromJson(e)).toList();
    } else {
      throw Exception(response.reasonPhrase);
    }
  }
}


model:
class UserModel {
  int? userId;
  int? id;
  String? title;
  String? body;

  UserModel({this.userId, this.id, this.title, this.body});

  UserModel.fromJson(Map<String, dynamic> json) {
    userId = json['userId'];
    id = json['id'];
    title = json['title'];
    body = json['body'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['userId'] = this.userId;
    data['id'] = this.id;
    data['title'] = this.title;
    data['body'] = this.body;
    return data;
  }
}

UI:

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider<AppsBloc>(
            create: (BuildContext context) => AppsBloc(AppRepostry()),
          )
        ],
        child: Scaffold(
          appBar: AppBar(
            title: const Text("key app top api"),
          ),
          body: BlocProvider(
            create: (context) => AppsBloc(
              AppRepostry(),
            )..add(LoadAppEvent()),
            child: BlocBuilder<AppsBloc, UsreState>(
              builder: (context, state) {
                if (state is LoadingAppState) {
                  return const Center(
                    child: CircularProgressIndicator(),
                  );
                }
                if (state is LoadedAppState) {
                  List<UserModel> usermodel = state.apps;
                  return ListView.builder(
                      itemCount: usermodel.length,
                      itemBuilder: (_, index) {
                        return Padding(
                          padding:
                              EdgeInsets.symmetric(vertical: 4, horizontal: 8),
                          child: Card(
                            color: Colors.deepPurpleAccent,
                            child: ListTile(
                              title: Text('${usermodel[index].title}'),
                            ),
                          ),
                        );
                      });
                }
                if (state is ErorrAppState) {
                  return const Center(
                    child: Text("No Data ERORR"),
                  );
                }
                return Container();
              },
            ),
          ),
        ));
  }
}

2

Answers


  1. https://jsonplaceholder.typicode.com/posts/1 response is a object not a list.

    object:

    {
     ...
     ...
    }
    

    list:

    {
       [
          ...
       ]
    }
    

    so in your case change return value on AppRepostry

    example:

    class AppRepostry {
    
      /// list ~
      Future<List<PostsEntity>> getPosts() async {
        const endpoint = 'https://jsonplaceholder.typicode.com/posts';
        final http.Response response = await http.get(Uri.parse(endpoint));
        if (response.statusCode == 200) {
          final List<dynamic> result = jsonDecode(response.body);
          return result.map((e) => PostsEntity.fromJson(e)).toList();
        } else {
          throw Exception(response.reasonPhrase);
        }
      }
    
      /// object
      Future<PostsEntity> getPost(int id) async {
        final endpoint = 'https://jsonplaceholder.typicode.com/posts/$id';
        http.Response response = await http.get(Uri.parse(endpoint));
        if (response.statusCode == 200) {
          // Decode the response body
          var decodedData = json.decode(response.body);
          return PostsEntity.fromJson(decodedData);
        } else {
          throw Exception(response.reasonPhrase);
        }
      }
    }
    
    Login or Signup to reply.
  2. The error you’re encountering, ‘_Map<String, dynamic>’ is not a subtype of type ‘List’, is due to the fact that the response from the API is a JSON object, but you are treating it as if it were a list in your getApp method.

    The API response looks like this:

    json:

    {"userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto"}
    

    It’s a JSON object ({}), not a JSON array ([]). So, you should decode it as a Map<String, dynamic> instead of a List.

    Here’s the corrected getApp method:

    class AppRepostry {
      Future<List<UserModel>> getApp() async {
        http.Response response = await http.get(Uri.parse(appUrl));
    
        if (response.statusCode == 200) {
          final Map<String, dynamic> result = jsonDecode(response.body);
    
          // Since the API returns a single object, we create a List with one element.
          return [UserModel.fromJson(result)];
        } else {
          throw Exception(response.reasonPhrase);
        }
      }
    }
    

    This way, you are treating the response as a single item list, and you are parsing the JSON object into a UserModel instance. In your LoadedAppState block, you can access the data like this:

    List<UserModel> usermodel = state.apps;
    UserModel userModel = usermodel[0]; // Since it's a single item list
    print(userModel.title); // Accessing the title property
    

    This should resolve the error you’re facing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search