自从我昨天开始在我的项目上编码以来,我面临着同样的问题,该项目的一部分是从给定的 api 获取一些 json 数据。
我的API链接是:http://alkadhum-col.edu.iq/wp-json/wp/v2/posts?_embed
我正在开发 flutter SDK,我很困惑为什么它不适合我!,我的工作是只获取链接、标题和 source_url 对象,但我无法获取它。
我在flutter文档中尝试了以下代码
https://flutter.dev/docs/cookbook/networking/fetch-data
根据我的需要进行一些修改后没有得到任何数据。
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Post> fetchPost() async {
final response =
await http.get('http://alkadhum-col.edu.iq/wp-json/wp/v2/posts/');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final int id;
String title;
String link;
Post({this.id, this.title, this.link});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'].toString(),
link: json['link'].toString()
);
}
}
void main() => runApp(MyApp(post: fetchPost()));
class MyApp extends StatelessWidget {
final Future<Post> post;
MyApp({Key key, this.post}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.link);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
),
),
),
);
}
}
我只收到以下讯息:
List 类型动态不是 Map String 类型的子类型,动态
任何帮助将不胜感激。
预先感谢。
您的 JSON 响应类型为
List<dynamic>
,但您正在 Map String, dynamic
中获取响应,但您可以执行类似的操作
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:clickmeetplay/iam/user/postbean.dart';
import 'package:http/http.dart' as http;
class PostHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold(body: PostScreen(),),);
}
}
class PostScreen extends StatefulWidget {
@override
_PostScreenState createState() => _PostScreenState();
}
class _PostScreenState extends State<PostScreen> {
List<Post> _postList =new List<Post>();
Future<List<Post> > fetchPost() async {
final response =
await http.get('http://alkadhum-col.edu.iq/wp-json/wp/v2/posts/');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
List<dynamic> values=new List<dynamic>();
values = json.decode(response.body);
if(values.length>0){
for(int i=0;i<values.length;i++){
if(values[i]!=null){
Map<String,dynamic> map=values[i];
_postList .add(Post.fromJson(map));
debugPrint('Id-------${map['id']}');
}
}
}
return _postList;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
@override
Widget build(BuildContext context) {
return Container();
}
@override
void initState() {
fetchPost();
}
}
Bean类
class Post {
final int id;
String title;
String link;
Post({this.id, this.title, this.link});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'].toString(),
link: json['link'].toString()
);
}
}
你需要改变你的班级。您需要根据 JSON 响应创建类结构。
class Post {
int id;
String title;
String link;
Post({this.id, this.title, this.link});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: title = json['title'] != null ? new Title.fromJson(json['title']) : null;
link: json['link'].toString()
);
}
}
class Title {
String rendered;
Title({this.rendered});
Title.fromJson(Map<String, dynamic> json) {
rendered = json['rendered'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['rendered'] = this.rendered;
return data;
}
}
然后,在您的 API 方法中。作为响应,您得到的是一个 JSON 数组。因此,将其放入列表中并将响应转换为 JSON 类。
Future<List<Post>> fetchPost() async {
final response =
await http.get('http://alkadhum-col.edu.iq/wp-json/wp/v2/posts/');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
var lst = response.body as List;
return lst.map((d) => Post.fromJson(d)).toList();
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
您始终可以使用 https://javiercbk.github.io/json_to_dart/ 等工具从复杂的 JSON 创建 Dart 类。这节省了很多时间。
您可以使用 Flutter 中的 http 包向 API 端点发出 HTTP GET 请求,然后使用 dart:convert 库的
jsonDecode
函数解析 JSON 响应。这是一个例子:
import 'package:http/http.dart' as http;
import 'dart:convert';
final response = await http.get(Uri.parse('https://example.com/api/data'));
final jsonData = jsonDecode(response.body);
尝试以下代码:
factory Post.fromMap(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'].cast<String>(),
link: json['link'].cast<String>()
);
}
**Create Api Class**
class ApiUtils {
static String baseUrl = "http://example/";
}
**Create Model**
class EventModel {
String title;
EventModel({this.title});
EventModel.fromJson(Map<String, dynamic> json) {
title = json['Title'] ?? "";
}
}
**Create Service**
import 'package:http/http.dart' as http;
import 'package:NoticeModel.dart';
import 'dart:convert';
class NoticeService {
bool error = false;
bool loading = true;
var notice;
bool noticeDetailserror = false;
bool noticeetailsloading = true;
Future<void> getNotice(dynamic input) async {
try {
noticeDetailserror = false;
http.Response response = await http.post(ApiUtils.noticeApi,
body: input, headers: {'Content-type': 'application/json'});
Map data = jsonDecode(response.body);
if (data["Status"] == true) {
notice = data["Data"];
notice = notice.map((_data) {
return new NoticeModel.fromJson(_data);
}).toList();
print(notice);
noticeetailsloading = false;
} else {
throw data;
}
} catch (e) {
print(e);
noticeetailsloading = false;
noticeDetailserror = true;
}
}
}
**Main Page**
var body =
json.encode({"IsActive": true, "IsDelete": false, "CompanyId": 18});
List<dynamic> data;
var count = 0;
bool loading = true;
bool error = false;
void getNoticeDetails() async {
setState(() {
error = false;
loading = true;
});
// SharedPreferences prefs = await SharedPreferences.getInstance();
NoticeService instance = NoticeService();
await instance.getNotice(body);
data = instance.notice;
if (instance.noticeDetailserror == false) {
setState(() {
count = data.length;
loading = false;
});
} else {
setState(() {
loading = false;
error = true;
});
Toast.show("Error Getting Data", context,
duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
}
}
@override
void initState() {
super.initState();
getNoticeDetails();
}
body: loading == true
? LinearProgressIndicator()
: error == true
? RetryWidget(
onRetry: getNoticeDetails,
)
: SafeArea(
SizedBox(
width: 270,
child: Text(
data[index].title ?? "",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 18,
color: Colors.grey,
fontWeight: FontWeight.bold,
),
),
),
)