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();
},
),