Trying to display in Flutter a result I am receiving from my Node.JS server via MySQL query:
[{"NAME":"Matematicas"},
{"NAME":"Naturales"},
{"NAME":"Ciencias Sociales"},
{"NAME":"Lenguaje"},
{"NAME":"Religion"}]
This is the class I am using in Flutter to handle it:
class Subject {
final String name;
Subject({
required this.name,
});
factory Subject.fromJson(Map<String, dynamic> json) {
return Subject(name: json['NAME']);
}
}
This is the method from which I obtain the data:
Future<Subject> fetchSubject() async {
var prefs = await SharedPreferences.getInstance();
var token = prefs.getString('token');
var response = await http.get(Uri.parse('http://localhost:8000/subjects'),
headers: {'x-access-token': token!});
print(response.body);
return Subject.fromJson(jsonDecode(response.body));
}
This is my initState
void initState() {
super.initState();
futureSubject = fetchSubject();
}
This is my Widget build piece:
Widget build(BuildContext context) {
return FutureBuilder<Subject>(
future: fetchSubject(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('Error'),
);
} else if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: Text('Materias'),
backgroundColor: Colors.green[300],
actions: [
Padding(
padding: EdgeInsets.only(right: 3.0),
child: IconButton(
icon: Icon(Icons.logout),
//TODO llamar funcion logout
onPressed: () {},
iconSize: 26,
),
)
],
),
body: Text(snapshot.data!.name));
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
}
This is what I get:
Uncaught (in promise) Error: Expected a value of type 'Map<String, dynamic>', but got one of type 'List<dynamic>'
I just want to display the information I am receiving as a List or table like fashion. Any ideas on what and how to refactor this?
CodePudding user response:
Its happened because your return data is an array. Try this
final data = json.decode(response.body);
return List<Subject>.from(data.map((value) => Subject.fromJson(value)));
CodePudding user response:
It looks like the fetchSubject
method needs to be modified and the widget itself. The data you displayed is a List of objects, thus the error that you are trying to see type Map<String, dynamic>
from jsonDecode(response.body)
but it returns a List<dynamic>
instead. Thus, you need to modify fetchSubject
and get a List<Subject
from your API not just an object. Or, you need to update an API. Just as an example (haven't tested it but should work):
Future<List<Subject>> fetchSubject() async {
var prefs = await SharedPreferences.getInstance();
var token = prefs.getString('token');
var response = await http.get(Uri.parse('http://localhost:8000/subjects'),
headers: {'x-access-token': token!});
print(response.body);
return jsonDecode(response.body).map((item) => Subject.fromJson(item));
}
and change all logic to handle a List
of Subject
and not just Subject
. The JSON your API returns is a list (array) of objects, not just an object.