Flutter snapshot.data为空。I';m使用for循环迭代JSON数据并创建对象实例列表
我正在从json-generator.com检索json数据,并对其进行解析,以在下面的代码中创建一个公司列表。打印JsonData变量时,可以看到数据,但snapshot.data为null。这是我的密码Flutter snapshot.data为空。I';m使用for循环迭代JSON数据并创建对象实例列表,flutter,dart,Flutter,Dart,我正在从json-generator.com检索json数据,并对其进行解析,以在下面的代码中创建一个公司列表。打印JsonData变量时,可以看到数据,但snapshot.data为null。这是我的密码 import 'package:flutter/material.dart'; import './Object.dart'; import 'dart:async'; import 'package:http/http.dart' as http; import 'UI_Styles/Co
import 'package:flutter/material.dart';
import './Object.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'UI_Styles/Company_Card_Style.dart';
import 'dart:convert';
class Companies extends StatefulWidget {
@override
_CompaniesState createState() => _CompaniesState();
}
class _CompaniesState extends State<Companies> {
Future<List<Company>> _getCompanies() async {
var data = await http.get("http://www.json-generator.com/api/json/get/bUYmnsimgi?indent=2");
var jsonData = json.decode(data.body);
List<Company> companies = [];
for (var c in jsonData) {
Company company = Company(
c["name"],
c["opportunites"],
c["address"],
c["city"],
c["state"],
c["country"],
c["zipcode"],
c["phone"],
c["timezone"],
c["pipelineRevenue"],
c["revenueAchieved"],
c["tags"]);
companies.add(company);
}
return companies;
}
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: _getCompanies(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return CompanyCardStyle(company: snapshot.data[index]);
});
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}));
}
}
我认为for循环存在一些问题,但我不知道出了什么问题。我不熟悉这样解析数据。这是因为FutureBuilder返回了一个错误事件。您可以通过访问
snapshot.error
(或snapshot.hasrerror
检查是否存在任何错误)来检查错误
当我尝试您的代码时,错误显示
需要一个'int'类型的值,但得到了'String'类型的值。
。在实例化Company
对象时,这似乎是个问题。一些属性(如opportunities
)需要int
,但您可以在String
中给出它,因为解码的json中的值是String。您需要首先将其解析为int
。我查看了网站,发现您的某些类型不正确。例如,标记是一个列表,但您将其作为字符串。电话号码也是一样,应该是字符串,而不是双精度的。由于您没有使用命名参数,因此无论何时创建该类的实例,都需要将构造函数中的属性按相同的顺序放置
class Company {
String name;
String address;
int opportunities;
int pipelineRevenue;
int revenueAchieved;
String city;
String state;
String country;
int zipcode;
String phone;
String timezone;
List tags;
Company(
this.name,
this.opportunities,
this.address,
this.city,
this.state,
this.country,
this.zipcode,
this.phone,
this.timezone,
this.pipelineRevenue,
this.revenueAchieved,
this.tags);
}
你做错了一些事情:
数据类型
(电话号码需要字符串
,但您使用了双精度
。标签也会返回列表
,但您使用了字符串
)
jsonData
转换为Company
对象时,您将大多数构造函数字段相互交换
公司
类创建工厂构造函数,使json反序列化更容易。您可以查看官方文档以获取示例标记
字段设置为字符串
,只访问来自api的列表中的第一个元素。
公司级
class公司{
字符串名;
字符串地址;
智力机会;
国际管道收入;
内部收入已完成;
字符串城市;
字符串状态;
弦国;
int-zipcode;
字符串电话;
字符串时区;
字符串标签;
公司(
这个名字,
这个地址,
这就是机遇,
这是我的收入,
这项收入已经实现,
这个城市,
这个州,
这个国家,
这个.zipcode,
这个电话,
这个时区,
这是"标签",;
//创建用于将json转换为公司对象的构造函数
factory Company.fromJson(映射json){
退货公司(
json[“名称”],
json[“地址”],
json[“机会”],
json[“pipelineRevenue”],
json[“revenueAchieved”],
json[“城市”],
json[“状态”],
json[“国家”],
json[“zipcode”],
json[“电话”],
json[“时区”],
json[“标记”][0],
);
}
}
- 公司小部件*
类公司扩展StatefulWidget{
@凌驾
_CompaniesState createState()=>\u CompaniesState();
}
类_CompaniesState扩展状态{
Future\u getCompanies()异步{
var data=wait http
.get(“http://www.json-generator.com/api/json/get/bUYmnsimgi?indent=2");
var jsonData=json.decode(data.body)作为列表;
上市公司=[];
//将json转换为公司列表
公司=jsonData
.map((公司)=>company.fromJson(公司))
.toList();//新行
印刷品(公司、长度);
返回公司;
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
主体:容器(
孩子:未来建设者(
未来:_getCompanies(),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
返回ListView.builder(
itemCount:snapshot.data.length,
itemBuilder:(构建上下文,int索引){
//在这里使用您的公司卡
返回文本(
'公司$索引名称:${snapshot.data[index.name}';
});
}否则{
返回中心(
子对象:CircularProgressIndicator(),
);
}
})),
);
}
}
您可能有兴趣看看这个线程:谢谢,我如何将它解析为int first in for loopAh看起来我错过了您实例化的顺序。看起来Unbreakable的答案是正确的。谢谢,它工作了,实现了命名参数部分,但没有初始化。谢谢您的努力,真的很感谢。我会吗完成factory函数。但是为什么在factory函数中的标记旁边放置[0],因为
标记
返回一个列表
,所以我选择了列表的第一个元素,因为我不知道你的公司卡片样式
是什么样子。好的!在你制作的演示应用程序中显示。明白了,谢谢
class Company {
String name;
String address;
int opportunities;
int pipelineRevenue;
int revenueAchieved;
String city;
String state;
String country;
int zipcode;
String phone;
String timezone;
List tags;
Company(
this.name,
this.opportunities,
this.address,
this.city,
this.state,
this.country,
this.zipcode,
this.phone,
this.timezone,
this.pipelineRevenue,
this.revenueAchieved,
this.tags);
}
class Company {
String name;
String address;
int opportunities;
int pipelineRevenue;
int revenueAchieved;
String city;
String state;
String country;
int zipcode;
String phone;
String timezone;
String tags;
Company(
this.name,
this.address,
this.opportunities,
this.pipelineRevenue,
this.revenueAchieved,
this.city,
this.state,
this.country,
this.zipcode,
this.phone,
this.timezone,
this.tags);
// make a constructor for converting json to a company object
factory Company.fromJson(Map<String, dynamic> json) {
return Company(
json["name"],
json["address"],
json["opportunities"],
json["pipelineRevenue"],
json["revenueAchieved"],
json["city"],
json["state"],
json["country"],
json["zipcode"],
json["phone"],
json["timezone"],
json["tags"][0],
);
}
}
class Companies extends StatefulWidget {
@override
_CompaniesState createState() => _CompaniesState();
}
class _CompaniesState extends State<Companies> {
Future<List<Company>> _getCompanies() async {
var data = await http
.get("http://www.json-generator.com/api/json/get/bUYmnsimgi?indent=2");
var jsonData = json.decode(data.body) as List;
List<Company> companies = [];
// convert the json to a list of companies
companies = jsonData
.map((company) => Company.fromJson(company))
.toList(); // new line
print(companies.length);
return companies;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: FutureBuilder(
future: _getCompanies(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
// use your company card here
return Text(
'Company $index name: ${snapshot.data[index].name}');
});
} else {
return Center(
child: CircularProgressIndicator(),
);
}
})),
);
}
}