我有一个从远程API获取一些数据的应用程序。因此,我将要接收并显示在JSON Future
中的数据:{"status":200,"out":{"summary":[{"bc":"1876","wc":"488679","pc":"731904"}],"last":[{"id":"1877","place":"7","publisher":"-1","bookid":"01877","title":"Neither Civil Nor Servant","author":"Peh","region":"\u65b0\u52a0\u5761","copyrighter":"","translated":"0","purchdate":"2017-04-18","price":"200.00","pubdate":"2016-01-01","printdate":"2016-01-01","ver":"1.1","deco":"\u666e\u901a","kword":"0","page":"220","isbn":"978-981-4642-63-7","category":"","location":"","intro":"TT\u8d60\u4e66\u3002","instock":"1","p_name":"\uff08\u672a\u6307\u5b9a\uff09"}]}}
我将从此JSON中提取out
字段,并将summary
和last
分配给两个变量:
initState() async {
var getter = createHttpClient();
String uri='http://api.rsywx.com/book/summary';
var res=await getter.get(uri);
Map data=JSON.decode(res.body);
var out=data['out'];
setState(() {
_today=formatDate(new DateTime.now());
_lb=out['last'][0];
_bs=out['summary'][0];
_lb['purchdate']=formatDate(DateTime.parse(_lb['purchdate']));
});
}
因此
_bs
和_lb
都是复合对象。在我的小部件
build
函数中,我将显示以下两个对象的内容: new TextSpan(
text: numFormatter.format(int.parse(_bs['bc'])),
style: aboutTextStyle,
),
该程序编译正常,但启动后会出现快速启动红屏:
很快,就会出现正确的屏幕:
我知道在初始
build
期间,对象_bs
和_lb
尚不存在,并且对远程API的异步调用仍试图填充返回的响应,因此在这种情况下,_bs['bc']
绝对不可调用。因此弹出非阻塞错误。解决方法
我可以通过声明一堆变量并在
initState
函数中分配它们来消除此错误;而不是渲染_bs['bc']
,我将渲染一个新变量_bookCoount
。这样,将在没有该红色屏幕的情况下完成渲染,并且该变量的值最初将为null
,并很快成为从远程API获取的正确值。但是,如果您明白我的意思,那就太麻烦了:很多只使用一次的变量。
或者,我是否应该在父级上获取数据,以便将其作为 Prop 传递给此小部件?尚未尝试。
感谢您的最佳做法投入。
更新
问题确实来自
int.parse
。如果我接了那个电话,程序将和平运行。所以现在的问题变成
我将抑制
int.parse
在要解析的值变为有效之前提示错误。 最佳答案
不确定您的解决方法是什么意思。在您的示例中,在setState()
返回值之前不会调用await getter.get(uri);
。
我想这应该做
new TextSpan(
text: _bs != null && _bs['bc'] != null ? [numFormatter.format(int.parse(_bs['bc'])) : 0,
style: aboutTextStyle,
),
关于dart - 无效的参数:来源不能为空,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43646511/