#mysql #node.js #flutter #dart
Вопрос:
Пытаюсь отобразить в Flutter результат, который я получаю от своего узла.JS-сервер с помощью запроса MySQL:
[{"NAME":"Matematicas"},
{"NAME":"Naturales"},
{"NAME":"Ciencias Sociales"},
{"NAME":"Lenguaje"},
{"NAME":"Religion"}]
Это класс, который я использую в Flutter для его обработки:
class Subject {
final String name;
Subject({
required this.name,
});
factory Subject.fromJson(Map<String, dynamic> json) {
return Subject(name: json['NAME']);
}
}
Это метод, с помощью которого я получаю данные:
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));
}
Это мое первоначальное состояние
void initState() {
super.initState();
futureSubject = fetchSubject();
}
Это моя часть сборки виджета:
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(),
);
}
});
}
Вот что я получаю:
Uncaught (in promise) Error: Expected a value of type 'Map<String, dynamic>', but got one of type 'List<dynamic>'
Я просто хочу отобразить информацию, которую я получаю, в виде списка или таблицы, как в моде. Есть какие-нибудь идеи о том, что и как это реорганизовать?
Ответ №1:
Это произошло потому, что ваши возвращаемые данные представляют собой массив. Попробуй это
final data = json.decode(response.body);
return List<Subject>.from(data.map((value) => Subject.fromJson(value)));
Комментарии:
1. С этим я, наконец, очень близок, только что получил это изображение:
[Instance of 'Subject', Instance of 'Subject', Instance of 'Subject', Instance of 'Subject', Instance of 'Subject']
2. Да, это потому, что каждый из них является объектом. В разделе
snapshot.hasData
создайте новыйList<Subject>
и сохранитеsnapshot.data
его. Чтобы отобразить все данные, используйтеListView
3. Да, это наконец сработало, спасибо!
Ответ №2:
Похоже fetchSubject
, что необходимо изменить метод и сам виджет. Отображаемые вами данные представляют собой список объектов, поэтому ошибка, из которой вы пытаетесь просмотреть тип Map<String, dynamic>
, jsonDecode(response.body)
но вместо этого она возвращает a List<dynamic>
. Таким образом, вам нужно изменить fetchSubject
и получить List<Subject
из вашего API не просто объект. Или вам нужно обновить API. Просто в качестве примера (не тестировал, но должен работать):
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));
}
и измените всю логику, чтобы справиться List
Subject
с проблемой, а не просто Subject
. JSON, возвращаемый вашим API, представляет собой список (массив) объектов, а не просто объект.
Комментарии:
1. Есть ошибка:
Expected a value of type 'FutureOr<List<Subject>>', but got one of type 'MappedListIterable<dynamic, dynamic>'