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

Time:11-15

I have a flutter project which is returning a list of data from an api in Json, I want to show the data as a list for a specific key which is name but currently I keep reciving:

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

Here is the future builder

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});
 
  @override
  State<HomeScreen> createState() => _HomeScreenState();
}
 
class _HomeScreenState extends State<HomeScreen> {
  late Future<Workouts_Model> futureWorkouts;
 
  @override
  void initState() {
    super.initState();
    futureWorkouts = APIService.fetchUserWorkout();
  }
...................................
            FutureBuilder<Workouts_Model>(
              future: futureWorkouts,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Text(snapshot.data!.name ?? 'noname');
                } else if (snapshot.hasError) ;
                print(snapshot.error);
                {
                  return Text('${snapshot.error}');
                }
                return const CircularProgressIndicator();
              },
            ),

Here is the api_caller:

  static Future<Workouts_Model> fetchUserWorkout() async {
    var url = Uri.parse(Config.apiURL   Config.userWorkoutsAPI);
 
    final response = await http.get(
      url,
      headers: {
        HttpHeaders.authorizationHeader:
            'Token XXXXXXXXXXXXXXX',
      },
    );
 
    final responseJson = jsonDecode(response.body);
    print(responseJson);
 
    if (response.statusCode == 200) {
      return Workouts_Model.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to load User');
    }
  }

Here is the model:

import 'dart:convert';
 
List<Workouts_Model> workoutsModelFromJson(String str) =>
    List<Workouts_Model>.from(
        json.decode(str).map((x) => Workouts_Model.fromJson(x)));
 
String workoutsModelToJson(List<Workouts_Model> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
 
class Workouts_Model {
  Workouts_Model({
    required this.id,
    required this.user,
    required this.name,
  });
 
  int id;
  String user;
  String name;
 
  factory Workouts_Model.fromJson(Map<String, dynamic> json) => Workouts_Model(
        id: json["id"],
        user: json["user"],
        name: json["name"],
      );
 
  Map<String, dynamic> toJson() => {
        "id": id,
        "user": user,
        "name": name,
      };
}

How to show the list of name in the model so that I can see it when the application is running.

CodePudding user response:

since I see that the API will return multiple elements, then it's a List right?

in this line:

      return Workouts_Model.fromJson(jsonDecode(response.body));

you're trying to assign a List to Map<String, dynamic>, which is wrong, you need to make a List<Workouts_Model> of the List of data in the API, so replace your method like this:

static Future<List<Workouts_Model>> fetchUserWorkout() async {
var url = Uri.parse(Config.apiURL   Config.userWorkoutsAPI);

final response = await http.get(
  url,
  headers: {
    HttpHeaders.authorizationHeader:
        'Token XXXXXXXXXXXXXXX',
  },
);

final responseJson = jsonDecode();
print(responseJson);

if (response.statusCode == 200) {
  return workoutsModelFromJson(response.body);
} else {
  throw Exception('Failed to load User');
}
}

then change this:

  late Future<Workouts_Model> futureWorkouts;

to this:

  late Future<List<Workouts_Model>> futureWorkouts;

then in your FutureBuilder:

   FutureBuilder<List<Workouts_Model>>(
          future: futureWorkouts,
          builder: (BuildContext context, AsyncSnapshot<List<Workouts_Model>> snapshot) {
            if (snapshot.hasData) {
              return Column(
               children: List.generate(snapshot.data!.length, (index) => Text(snapshot.data![index].name ?? 'noname')));
            } else if (snapshot.hasError) ;
            print(snapshot.error);
            {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
  • Related