我看了很多例子和类似的问题后问,但我不能得到我的头。我只是想从json映射到Flutter的id中获得某些数据。我通过php收到的是2串JSON(这是正确的JSON我已经检查过jsonlint):
[{"id":1,"firstname":"John","surname":"Wick","guitarbrand":"Ibanez","votes":15,"pickups":2},{"id":2,"firstname":"Elvis","surname":"Presley","guitarbrand":"LesPaul","votes":10,"pickups":1},{"id":3,"firstname":"Kirk","surname":"Hammet","guitarbrand":"HarleyBenton","votes":9,"pickups":3}]
{"id":1,"firstname":"John","surname":"Wick","guitarbrand":"Ibanez","votes":15,"pickups":2}
我使用一个单独的Dart文件,我导入到main.dart:
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<Dayplay> fetchDayplay() async {
final resp1 = await http.get(Uri.parse('http://somewhere.com/getdayentries.php'));
if (resp1.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print('Response body: ${json.decode((resp1.body))}');
return Dayplay.fromJson(jsonDecode(resp1.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
Future<Winner> fetchWinner() async {
final resp2 = await http.get(Uri.parse('http://somewhere.com/getwinner.php'));
if (resp2.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print('Response body: ${json.decode((resp2.body))}');
return Winner.fromJson(jsonDecode(resp2.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
class Dayplay {
int? _id;
String? _firstname;
String? _surname;
String? _guitarbrand;
int? _votes;
int? _pickups;
Dayplay(
{int? id,
String? firstname,
String? surname,
String? guitarbrand,
int? votes,
int? pickups}) {
if (id != null) {
this._id = id;
}
if (firstname != null) {
this._firstname = firstname;
}
if (surname != null) {
this._surname = surname;
}
if (guitarbrand != null) {
this._guitarbrand = guitarbrand;
}
if (votes != null) {
this._votes = votes;
}
if (pickups != null) {
this._pickups = pickups;
}
}
int? get id => _id;
set id(int? id) => _id = id;
String? get firstname => _firstname;
set firstname(String? firstname) => _firstname = firstname;
String? get surname => _surname;
set surname(String? surname) => _surname = surname;
String? get guitarbrand => _guitarbrand;
set guitarbrand(String? guitarbrand) => _guitarbrand = guitarbrand;
int? get votes => _votes;
set votes(int? votes) => _votes = votes;
int? get pickups => _pickups;
set pickups(int? pickups) => _pickups = pickups;
Dayplay.fromJson(Map<String, dynamic> json) {
_id = json['id'];
_firstname = json['firstname'];
_surname = json['surname'];
_guitarbrand = json['guitarbrand'];
_votes = json['votes'];
_pickups = json['pickups'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this._id;
data['firstname'] = this._firstname;
data['surname'] = this._surname;
data['guitarbrand'] = this._guitarbrand;
data['votes'] = this._votes;
data['pickups'] = this._pickups;
return data;
}
}
class Winner {
int? _id;
String? _firstname;
String? _surname;
String? _guitarbrand;
int? _votes;
int? _pickups;
Winner(
{int? id,
String? firstname,
String? surname,
String? guitarbrand,
int? votes,
int? pickups}) {
if (id != null) {
this._id = id;
}
if (firstname != null) {
this._firstname = firstname;
}
if (surname != null) {
this._surname = surname;
}
if (guitarbrand != null) {
this._guitarbrand = guitarbrand;
}
if (votes != null) {
this._votes = votes;
}
if (pickups != null) {
this._pickups = pickups;
}
}
int? get id => _id;
set id(int? id) => _id = id;
String? get firstname => _firstname;
set firstname(String? firstname) => _firstname = firstname;
String? get surname => _surname;
set surname(String? surname) => _surname = surname;
String? get guitarbrand => _guitarbrand;
set guitarbrand(String? guitarbrand) => _guitarbrand = guitarbrand;
int? get votes => _votes;
set votes(int? votes) => _votes = votes;
int? get pickups => _pickups;
set pickups(int? pickups) => _pickups = pickups;
Winner.fromJson(Map<String, dynamic> json) {
_id = json['id'];
_firstname = json['firstname'];
_surname = json['surname'];
_guitarbrand = json['guitarbrand'];
_votes = json['votes'];
_pickups = json['pickups'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this._id;
data['firstname'] = this._firstname;
data['surname'] = this._surname;
data['guitarbrand'] = this._guitarbrand;
data['votes'] = this._votes;
data['pickups'] = this._pickups;
return data;
}
}
这部分是Main。在需要数据的地方:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:fiveupmusic/getdata.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
var idctl = "";
late bool error, sending, success;
late Future<Dayplay> futureDayplay;
late Future<Winner> futureWinner;
@override
void initState() {
futureDayplay = fetchDayplay();
futureWinner = fetchWinner();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: FutureBuilder(
future: futureDayplay,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.bandname);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
print("snapshot");
print(snapshot.data);
return SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Image.asset('assets/images/top_logo_320x40.jpg'),
Center(child: Text('Result: (how do I get the variable data here?)',
style: TextStyle(
color: Colors.lightBlue[100],
),
)),..............
-我可以在同一个FutureBuilder中使用2个期货吗?我需要从两个JSON字符串的数据
-如何从某个id检索数据?
我可以通过打印命令看到数据,我得到这个:
E/flutter (27453): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
E/flutter (27130): <asynchronous suspension>
我不明白为什么在第一个JSON数据之后它给出了这个错误在接收到第二个字符串之后,就没有错误了。我在Android Studio中没有任何其他错误。
感谢您提供更多关于如何解决这个问题的见解。
这样做的一种方法是使用Future.wait
等待两个调用。data
则是结果列表。使用firstWhere
从列表中查找对象
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: FutureBuilder(
future: Future.wait([fetchPosts(), fetchUser()]),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('${snapshot.error}');
} else if (snapshot.hasData) {
final posts = (snapshot.data as List)[0] as List<dynamic>;
final user = (snapshot.data as List)[1];
final userId = user['id'];
final post = posts.firstWhere((post) => post['userId'] == userId);
return Text('$post');
} else {
return const Text('Loading ...');
}
}
)
),
),
);
}
Future<List<dynamic>> fetchPosts() async {
final resp1 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (resp1.statusCode == 200) {
return json.decode((resp1.body));
} else {
throw Exception('Failed to load');
}
}
Future<Map<String,dynamic>> fetchUser() async {
final resp2 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users/1'));
if (resp2.statusCode == 200) {
return json.decode((resp2.body));
} else {
throw Exception('Failed to load');
}
}
}