2017-04-27 203 views
2

我有這個應用程序從遠程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場和assing summarylast兩個變量:

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, 
), 

程序編譯確定,但推出的時候,快速閃紅屏將出現:

enter image description here

很快,正確的屏幕將出現:enter image description here

我知道在最初的build期間,對象_bs_lb尚未存在,並且對遠程API的異步調用仍在嘗試填充返回的響應,因此在這種情況下,將無法調用_bs['bc']。因此彈出非阻塞錯誤。

解決方法

我可以通過聲明一組變量消除這個錯誤,並在initState功能爲它們分配;而不是渲染_bs['bc'],我會渲染一個新變量_bookCoount。這樣,渲染將在沒有這個紅色屏幕的情況下完成,並且該變量的值最初將爲null,並且很快將成爲從遠程API獲取的正確值。

但是這太麻煩了,如果你明白我的意思:很多隻用一次的變量。

或者,我應該將數據提取到父級別上,以便它將作爲道具傳遞給此小部件?尚未嘗試。

希望您的最佳實踐輸入。

更新

問題真的來自int.parse。如果我拿出那個電話,程序就會平靜地運行。

所以,現在的問題變成

我會抑制int.parse提示錯誤之前它會解析值有效。

+0

如果您在控制檯看,你會看到更詳細的錯誤報告,包括堆棧跟蹤,準確顯示錯誤所在。 –

回答

1

不確定您的解決方法是什麼意思。在你的例子中setState()await getter.get(uri);返回一個值之前不會被調用。

我想這應該做

new TextSpan(
    text: _bs != null && _bs['bc'] != null ? [numFormatter.format(int.parse(_bs['bc'])) : 0, 
    style: aboutTextStyle, 
), 
+0

這可以解決。比我聲明所有變量更好。 – TaylorR