я новичок в флаттере, и я встречаю этот API со сложным json «MAP». Что я хочу, так это отобразить список стран с их подробностями в списке флаттера. Как я могу этого добиться? Большинство ответов объясняют «СПИСОК» json.
{
"status": "Request is successful",
"message": null,
"data": {
"page": 1,
"last_page": 125,
"page_size": 2,
"countries": [
{
"id": "1",
"attributes": {
"name": "Grenada",
"code": "GD",
"subregion": "Caribbean",
"flag": "https://flagcdn.com/gd.svg",
"postalcode": "",
"latitude": "12.11666666",
"longitude": "-61.66666666",
"createdAt": "2023-01-11T22:15:40.000000Z",
"updatedAt": "2023-01-11T22:15:40.000000Z"
}
},
{
"id": "2",
"attributes": {
"name": "Malaysia",
"code": "MY",
"subregion": "South-Eastern Asia",
"flag": "https://flagcdn.com/my.svg",
"postalcode": "^(\\d{5})$",
"latitude": "2.5",
"longitude": "112.5",
"createdAt": "2023-01-11T22:15:40.000000Z",
"updatedAt": "2023-01-11T22:15:40.000000Z"
}
}
]
}
}
Я нашел этот проект GitHub с этими файлами json , modelClass Mainclass, которые связаны с концепцией, но у меня есть одна дополнительная фигурная скобка (карта), поэтому я не знаю, как достичь цели .
если есть какие-либо предложения или лучший способ кодирования, пожалуйста, помогите мне.
вот как они создали в модельном классе но, но это не работает со мной.
class Product {
final List<Result> results;
Product({this.results});
factory Product.fromJson(Map<String, dynamic> data) {
var list = data['data']['result'] as List;
List<Result> resultList = list.map((e) => Result.fromJson(e)).toList();
return Product(
results: resultList,
);
}
}
что я сделал
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
var data_from_link;
getData() async {
final String link = 'myurl';
data_from_link = await http.get(Uri.parse(link), headers: {"Accept": "application/json"});
final res = jsonDecode(data_from_link.body) as Map<String, dynamic>;
final List<Country> list= (res['data']['countries'] as List<dynamic>).map((e) => Country.fromJson(e))
.toList();
}
@override
void initState() {
super.initState();
getData();
}
@override
Widget build(BuildContext context) {
final res = jsonDecode(data_from_link.body) as Map<String, dynamic>;
final List<Country> list= (res['data']['countries'] as List<dynamic>).map((e) => Country.fromJson(e))
.toList();
return ListView.builder(
itemCount: list.length,
itemBuilder: (_, i) => ListTile(
title: Text(
list![i].attributes.name,
),
subtitle: Text(list![i].attributes.code),
)
);
}
}
Вы можете создать два класса для Country
и Attribute
class Country {
const Country({required this.id, required this.attributes});
/// Creates a Country from Json map
factory Country.fromJson(Map<String, dynamic> json) => Country(
id: json['id'] as String,
attribute:
Attribute.fromJson(json['attributes'] as Map<String, dynamic>),
);
/// A description for id
final String id;
final Attribute attributes;
}
class Attribute {
const Attribute({
required this.name,
required this.code,
required this.createdAt,
required this.updatedAt,
});
/// Creates a Attribute from Json map
factory Attribute.fromJson(Map<String, dynamic> json) => Attribute(
name: json['name'] as String,
code: json['code'] as String,
createdAt: DateTime.parse(json['createdAt'] as String),
updatedAt: DateTime.parse(json['updatedAt'] as String),
);
final String name;
final String code;
final DateTime createdAt;
final DateTime updatedAt;
}
при расшифровке:
final res = jsonDecode(json) as Map<String, dynamic>;
final List<Country> list = (res['data']['countries'] as
List<dynamic>)
.map((e) => Country.fromJson(e))
.toList();
Спасибо, но как я могу распечатать или вызвать данные из атрибута страны после декодирования, потому что, когда я пытаюсь что-то вроде Print (список.страна.атрибут.имя) . Я провалился. Моя цель - показать на Посмотреть список
Вы можете использовать его следующим образом:
ListView.builder(
itemCount: list.length,
itemBuilder: (_, i) => ListTile(
title: Text(
list[i].attributes.name,
),
subtitle: Text(list[i].attributes.code),
)),
ОБНОВЛЯТЬ
import 'package:flutter/material.dart';
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
late Future<List<Country>> futureList;
Future<List<Country>?> getData() async {
final String link = 'yoururl';
final res = await http
.get(Uri.parse(link), headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
final List<Country> list = (res['data']['countries'] as List<dynamic>)
.map((e) => Country.fromJson(e))
.toList();
return list;
} else {
throw Exception('Failed to fetch data');
}
}
@override
void initState() {
super.initState();
futureList = getData();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: futureList,
builder: (context, snapshot) {
if (snapshot.hasData) {
final list = snapshot.data;
return ListView.builder(
itemCount: list!.length,
itemBuilder: (_, i) => ListTile(
title: Text(
list![i].attributes.name,
),
subtitle: Text(list![i].attributes.code),
),
);
} else if (snapshot.hasError) {
return const Text('error fetching data');
}
return const CircularProgressIndicator();
},
);
}
}
я следовал тому, что вы мне показали, и я получаю эту ошибку. Метод «тело» не найден. Получатель: null Аргументы: [] позвольте мне отредактировать вопрос части, чтобы вы могли видеть
После первого добавления виджета материала, такого как виджет Scaffold, перед FutureBuilder, второго добавления final response= jsonDecode(res.body) as Map<String, dynamic>; и в-третьих, после замены res['data'] на response['data'] это наконец сработало.
Спасибо, Солиев, за вашу помощь, вы можете внести эти изменения, чтобы другие могли проголосовать за ваш ответ.
Спасибо, но как я могу распечатать или вызвать данные из атрибута страны после декодирования, потому что, когда я пытаюсь что-то вроде Print (list.country.attribute.name) . Я провалился. Моя цель - отобразить в Listview. Пожалуйста, помогите мне, у меня есть четыре дня, чтобы понять это.