【问题标题】:The method '[]' was called on null. Receiver: null在 null 上调用了方法“[]”。接收方:空
【发布时间】:2020-09-11 22:01:09
【问题描述】:

为了隔离问题,我创建了一个新代码、一个新程序和一台新机器。 相同的结果,它只是不想打印在 "quotes" 之后并具有 "anythingPrice" 的任何值

再一次,我可以给你一个临时密钥,你可以完全运行代码。在你身边。

请告诉我。

import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
//import 'package:flutter_web/material.dart';
//import 'package:flutter/main.dart' as app;
//import 'package:flutter_web_ui/ui.dart' as ui;


Future<List<Photo>> fetchPhotos(http.Client client) async {
  final response =
 // await client.get('https://cloud.iexapis.com/stable/stock/market/batch?symbols=CNPF,ICOL,PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,IEI,TLH,DIA,BSJF,MONY&types=quote,stats&token=');

  await client.get('https://cloud.iexapis.com/stable/stock/market/batch?symbols=PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,PGF,SNLN,DVHL,AUNZ,MDIV,PHB,PFXF,FPE,TIPX,MLN,SDIV,SIPE,SEMF,EMAG,IEMF,EU,BSCM,LEMF,BSCL,BSCK,BSCJ,BSCI,DSUM,BSCF,KBWD,PCEF,BSCG,BSCH,HYEM,ITM,BKLN,PGHY,IBCE,PZT,IJNK,XMPT,THHY,QYLD,IHY,IYLD,SHYD,PRB,DVHI,GOVT,BSJJ,BSJK,RIGS,INY,IBCD,PZA,PFIG,IBCC,BSCE,PVI,MBG,CXA,FWDB,DIV,CHLC,BSJI,FLTR,PWZ,MUAH,IBDD,PICB,IBDB,BSJH,RVNU,BSJG,IBDC,XOVR,BSJE,EBND,PCY,BWX,SJNK,DES,ANGL,BAB,SST,EMCD,CBND,HYD,PLW,SCPB,FLRN,BWZ,KBWY,ELD,IBND,AOK,RWXL,ITR,DON,DGRS,JNK,TZD,EPU,PFF,HYLD,GGOV,ULST,SPHD,HFIN,DGRW,LWC,ALD,LEMB,AGND,ITIP,EMHY,QLTC,TFI,SRLN,HYLS,SHM,GNMA,CEMB,IGOV,MINC,AGZD,FTSL,SPLV,GHYG,ISTB,ENGN,CMBS,GTIP,SCHO,SMMU,QLTA,SCHZ,HSPX,TUZ,GIY,GSY,TFLO,VMBS,CWB,FLOT,STPZ,MUAC,SCHR,BABZ,HYXU,GMTB,MUNI,WIP,MUAD,QLTB,SCHP,GMMB,MUAE,IPE,NYF,BNDX,MUAF,HYMB,TIPZ,CMF,LAG,ILTB,ITE,CLY,VGSH,VGIT,LTPZ,BABS,HYHG,EMCB,DVYL,VGLT,DHS,TLO,VWOB,IGHG,GLCB,RAVI,VCSH,BSV,BND,BIV,ISHG,SDYL,VCIT,SHY,BLV,HYG,VCLT,TENZ,DTN,BIL,AUD,DLN,DTD,FTSD,CAD,STIP,CORP,HYS,HOLD,TRSY,IEF,IBDA,COBO,BOND,MINT,MBB,CSJ,AGG,SUB,EMB,CIU,GVI,MUB,GBF,TIP,AGZ,CFT,LQD,TLT,IEI,TLH,DIA,BSJF,MONY&types=stats,quote&token=');
  //https://cloud.iexapis.com/v1/stock/market/batch?&types=price&symbols=aapl,fb,tsla&token=YOUR_TOKEN_HERE
  //https://cloud.iexapis.com/v1/stock/market/batch?&types=quote&symbols=aapl,fb,tsla&token=
  // Use the compute function to run parsePhotos in a separate isolate.
  //https://cloud.iexapis.com/stable/stock/market/batch?symbols=CNPF,ICOL,PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,PGF,SNLN,DVHL,AUNZ,MDIV,PHB,PFXF,FPE,TIPX,MLN,SDIV,SIPE,SEMF,EMAG,IEMF,EU,BSCM,LEMF,BSCL,BSCK,BSCJ,BSCI,DSUM,BSCF,KBWD,PCEF,BSCG,BSCH,HYEM,ITM,BKLN,PGHY,IBCE,PZT,IJNK,XMPT,THHY,QYLD,IHY,IYLD,SHYD,PRB,DVHI,GOVT,BSJJ,BSJK,RIGS,INY,IBCD,PZA,PFIG,IBCC,BSCE,PVI,MBG,CXA,FWDB,DIV,CHLC,BSJI,FLTR,PWZ,MUAH,IBDD,PICB,IBDB,BSJH,RVNU,BSJG,IBDC,XOVR,BSJE,EBND,PCY,BWX,SJNK,DES,ANGL,BAB,SST,EMCD,CBND,HYD,PLW,SCPB,FLRN,BWZ,KBWY,ELD,IBND,AOK,RWXL,ITR,DON,DGRS,JNK,TZD,EPU,PFF,HYLD,GGOV,ULST,SPHD,HFIN,DGRW,LWC,ALD,LEMB,AGND,ITIP,EMHY,QLTC,TFI,SRLN,HYLS,SHM,GNMA,CEMB,IGOV,MINC,AGZD,FTSL,SPLV,GHYG,ISTB,ENGN,CMBS,GTIP,SCHO,SMMU,QLTA,SCHZ,HSPX,TUZ,GIY,GSY,TFLO,VMBS,CWB,FLOT,STPZ,MUAC,SCHR,BABZ,HYXU,GMTB,MUNI,WIP,MUAD,QLTB,SCHP,GMMB,MUAE,IPE,NYF,BNDX,MUAF,HYMB,TIPZ,CMF,LAG,ILTB,ITE,CLY,VGSH,VGIT,LTPZ,BABS,HYHG,EMCB,DVYL,VGLT,DHS,TLO,VWOB,IGHG,GLCB,RAVI,VCSH,BSV,BND,BIV,ISHG,SDYL,VCIT,SHY,BLV,HYG,VCLT,TENZ,DTN,BIL,AUD,DLN,DTD,FTSD,CAD,STIP,CORP,HYS,HOLD,TRSY,IEF,IBDA,COBO,BOND,MINT,MBB,CSJ,AGG,SUB,EMB,CIU,GVI,MUB,GBF,TIP,AGZ,CFT,LQD,TLT,IEI,TLH,DIA,BSJF,MONY&types=quote,stats&token=
  return compute(parsePhotos, response.body);
}

// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
  //final parsed = json.decode(responseBody).cast<Map<String,dynamic>>();

  //return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();

  dynamic Obj = json.decode(responseBody);
  debugPrint(responseBody, wrapWidth: 8192);
  print(Obj.length);

  List<Photo> photoList = [];
  Obj.forEach((k, v) => photoList.add(Photo(k,v)));

  return photoList;
}

class Photo {
  String symbol;
  //String companyName;
  dynamic data;
 // dynamic iexClose;
 // dynamic quote;
  Photo(this.symbol ,this.data);


}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override

  Widget build(BuildContext context) {

    final appTitle = 'Monthly Paying ETFs';

    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),

    );
  }
}

class MyHomePage extends StatelessWidget {


  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {


    return Scaffold(

        drawer: Drawer(
          // Add a ListView to the drawer. This ensures the user can scroll
          // through the options in the drawer if there isn't enough vertical
          // space to fit everything.
          child: ListView(
            // Important: Remove any padding from the ListView.
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('About'),
                decoration: BoxDecoration(
                  color: Colors.grey,
                ),
              ),
              ListTile(
                title: Text('This app is to provide the list of ETF s that pay monthly dividend'),

                onTap: () {
                  // Update the state of the app
                  // ...
                  // Then close the drawer
                  Navigator.pop(context);
                },


              ),
              ListTile(
                title: Text('for questions or feedback please contact me at  '),

                onTap: () {
                  // Update the state of the app
                  // ...
                  // Then close the drawer
                  Navigator.pop(context);
                },


              ),

            ],
          ),
        ),

        appBar: AppBar(
        title: Text(title),
          backgroundColor: Colors.greenAccent,
      ),

      body: FutureBuilder<List<Photo>>(

        future: fetchPhotos(http.Client()),

        builder: (context, snapshot) {
          if (snapshot.hasError) print(snapshot.error);

          return snapshot.hasData
              ? PhotosList(photos: snapshot.data)
              : Center(child: CircularProgressIndicator());

        },
      ),
    );
  }
}


class PhotosList extends StatefulWidget {
  final List photos;

  PhotosList({Key key, this.photos})
      : assert(photos != null),
        super(key: key);

  @override
  _PhotosListState createState() => _PhotosListState();
}

class _PhotosListState extends State<PhotosList> {
  @override




  Widget build(BuildContext context) {



    return bodyData();

  }


  SingleChildScrollView bodyData() =>

    SingleChildScrollView(
  scrollDirection: Axis.vertical,

      // padding: EdgeInsets.all(0.0),
       //padding: const EdgeInsets.symmetric(
       //  padding: new EdgeInsets.fromLTRB(0.001, .001, 1.0, 1.0),
       padding: EdgeInsets.all(0.05),


 // child: FittedBox(fit:BoxFit.contain,

  child:SingleChildScrollView(
    scrollDirection: Axis.horizontal,

  child:
  FittedBox(
  fit: BoxFit.fitHeight,
  child: DataTable(
         // sortColumnIndex: 1,
        //  sortAscending: true,

          columns: <DataColumn>[
            DataColumn(
              label: Text("Company"),
              onSort: (_, __) {
                setState(() {
                  widget.photos.sort((a, b) =>
                      a.data["quote"]["companyName"]
                          .compareTo(b.data["quote"]["companyName"]));
                });
              },
            ),


            DataColumn(
              label: Text("ttmDivRate"),
              numeric: true,
              onSort:   (_,__) {
                setState(() {
                  widget.photos.sort((a, b) =>
                      a.data["quote"]["ttmDividendRate"]
                          .compareTo(b.data["quote"]["ttmDividendRate"]));
                });
              },
            ),

            DataColumn(
              label: Text("Price"),
              numeric: true,
              onSort: (_, __) {
                setState(() {
                  widget.photos.sort((a, b) => a.data ["quote"]["latestPrice"]
                      .compareTo(b.data["quote"]["latestPrice"]));
                });
              },
            ),



          ],

          rows: widget.photos

              .map(
                (photo) =>

                DataRow(
                  cells: [



                    DataCell(
                      Text('${photo.data["stats"]["companyName"] ?? ""}'),
                    ),

                    DataCell(
                      Text('${photo.data["stats"]["ttmDividendRate"] ?? ""}'),
                   ),
//["quote"]["stats"]
                    DataCell(
                      Text('${photo.data["quote"]["stats"]["latestPrice"] ?? ""}')
                    ),

                  ],
                ),

          )

              .toList())


),
   ),

    );


}

问题是值在那里,当输出在控制台中时,Flutter 说是 null。

===================
Launching lib/main.dart on iPhone 11 Pro Max in debug mode...
Running Xcode build...
Xcode build done.                                           17.9s
Waiting for iPhone 11 Pro Max to report its views...
Debug service listening on ws://127.0.0.1:57768/yyPV-GQyldg=/ws
Syncing files to device iPhone 11 Pro Max...
flutter: {"PGX":{"stats":{"week52change":-0.025465,"week52high":15.28,"week52low":9.71,"marketcap":4595628000,"employees":null,"day200MovingAvg":14.55,"day50MovingAvg":13.39,"float":null,"avg10Volume":2336007.5,"avg30Volume":2648722.77,"ttmEPS":null,"ttmDividendRate":0.8361,"companyName":"Invesco Preferred ETF","sharesOutstanding":324550000,"maxChangePercent":-0.3042,"year5ChangePercent":-0.0367,"year2ChangePercent":-0.0167,"year1ChangePercent":-0.025465,"ytdChangePercent":-0.064111,"month6ChangePercent":-0.045822,"month3ChangePercent":-0.052209,"month1ChangePercent":0.019438,"day30ChangePercent":0.028322,"day5ChangePercent":0.015054,"nextDividendDate":"2020-05-18","dividendYield":0.059046610169491524,"nextEarningsDate":null,"exDividendDate":"2020-05-18","peRatio":null,"beta":0.5684535732534528},"quote":{"symbol":"PGX","companyName":"Invesco Preferred ETF","primaryExchange":"NYSE Arca","calculationPrice":"close","open":14.11,"openTime":1590154200191,"openSource":"official","close":14.16,"closeT<…>
flutter: 2020","latestUpdate":1590177600180,"latestVolume":4747,"iexRealtimePrice":null,"iexRealtimeSize":null,"iexLastUpdated":null,"delayedPrice":11.245,"delayedPriceTime":1590192000004,"oddLotDelayedPrice":11.193,"oddLotDelayedPriceTime":1590173727614,"extendedPrice":11.245,"extendedChange":0.005,"extendedChangePercent":0.00044,"extendedPriceTime":1590186600005,"previousClose":11.16,"previousVolume":8688,"change":0.08,"changePercent":0.00717,"volume":4747,"iexMarketPercent":null,"iexVolume":null,"avgTotalVolume":12262,"iexBidPrice":null,"iexBidSize":null,"iexAskPrice":null,"iexAskSize":null,"iexOpen":null,"iexOpenTime":null,"iexClose":11.04,"iexCloseTime":1589988569572,"marketCap":35406000,"peRatio":null,"week52High":16.6,"week52Low":8.47,"ytdChange":-0.300712,"lastTradeTime":1590177600181,"isUSMarketOpen":false}},"IPFF":{"stats":{"week52change":-0.23383400000000001,"week52high":15.71,"week52low":8.38,"marketcap":28738500,"employees":null,"day200MovingAvg":13.89,"day50MovingAvg":10.96,"float<…>
flutter: 95
flutter: {"PGX":{"stats":{"week52change":-0.025465,"week52high":15.28,"week52low":9.71,"marketcap":4595628000,"employees":null,"day200MovingAvg":14.55,"day50MovingAvg":13.39,"float":null,"avg10Volume":2336007.5,"avg30Volume":2648722.77,"ttmEPS":null,"ttmDividendRate":0.8361,"companyName":"Invesco Preferred ETF","sharesOutstanding":324550000,"maxChangePercent":-0.3042,"year5ChangePercent":-0.0367,"year2ChangePercent":-0.0167,"year1ChangePercent":-0.025465,"ytdChangePercent":-0.064111,"month6ChangePercent":-0.045822,"month3ChangePercent":-0.052209,"month1ChangePercent":0.019438,"day30ChangePercent":0.028322,"day5ChangePercent":0.015054,"nextDividendDate":"2020-05-18","dividendYield":0.059046610169491524,"nextEarningsDate":null,"exDividendDate":"2020-05-18","peRatio":null,"beta":0.5684535732534528},"**quote":{"symbol":"PGX","companyName":"Invesco Preferred ETF","primaryExchange":"NYSE Arca","calculationPrice":"close","open":14.11,"openTime":1590154200191,"openSource":"official","close":14.16,"closeT<…>
flutter: 2020","latestUpdate":1590177600180,"latestVolume":4747,"iexRealtimePrice":null,"iexRealtimeSize":null,"iexLastUpdated":null,"delayedPrice":11.245,"delayedPriceTime":1590192000004,"oddLotDelayedPrice":11.193,"oddLotDelayedPriceTime":1590173727614,"extendedPrice":11.245,"extendedChange":0.005,"extendedChangePercent":0.00044,"extendedPriceTime":1590186600005,"previousClose":11.16,"previousVolume":8688,"change":0.08,"changePercent":0.00717,"volume":4747,"iexMarketPercent":null,"iexVolume":null,"avgTotalVolume":12262,"iexBidPrice":null,"iexBidSize":null,"iexAskPrice":null,"iexAskSize":null,"iexOpen":null,"iexOpenTime":null,"iexClose":11.04,"iexCloseTime":1589988569572,"marketCap":35406000,"peRatio":null,"week52High":16.6,"week52Low":8.47,"ytdChange":-0.300712,"lastTradeTime":1590177600181,"isUSMarketOpen":false}},"IPFF":{"stats":{"week52change":-0.23383400000000001,"week52high":15.71,"week52low":8.38,"marketcap":28738500,"employees":null,"day200MovingAvg":13.89,"day50MovingAvg":10.96,"float<…>
flutter: 95**

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building photorealist(dirty, state: _PhotosListState#8eef8):
The method '[]' was called on null.
Receiver: null
Tried calling: []("iexClose")

============== 价格栏为空。 如果我尝试调用 "delayedPrice":11.552," 或 "iexClose":11.04.,它不会在应用程序中打印。

【问题讨论】:

  • @chunhunghan ══════════════════════════════════════════ ═══════════════ 在构建 photorealist(dirty, state: _PhotosListState#8eef8) 时引发了以下 NoSuchMethodError:在 null 上调用了方法“[]”。接收者:null 尝试调用:
  • 我认为您在使用模型获取然后保存/使用数据时遇到了问题。您应该看看这个答案,然后尝试实施并获取数据。 stackoverflow.com/a/58708634/9236994
  • 是的,无论 ""quote":{"symbol":"PGX","companyName":"Invesco Preferred ETF","primaryExchange":"NYSE Arca","calculationPrice": "close","open":14.11,"openTime":1590154200191,"openSource":"official","close":14.16,"closeT<...> flutter:" 打不开。以前可以用. 我不记得有任何变化。我认为是 Flutter 问题。
  • 如果您在尝试使用上述答案中提到的方法构建模型时收到错误,那么很可能您的输出的 json 响应结构有问题。
  • 我同意。问题是什么。我照旧工作。

标签: flutter dart


【解决方案1】:

我已经检查了您共享的令牌并测试了您共享的代码。

您从引发错误的地方以错误的方式调用数组。

我试过了,输出显示没有任何错误

  DataCell(
      Text('${photo.data["quote"]["stats"]["latestPrice"] ?? ""}')   //❌
      //REPLACE   ["quote"]["stats"]    with   ["stats"]
      Text('${photo.data["stats"]["latestPrice"] ?? ""}')   //✔️
  ),

输出:

工作代码

import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
//import 'package:flutter_web/material.dart';
//import 'package:flutter/main.dart' as app;
//import 'package:flutter_web_ui/ui.dart' as ui;

Future<List<Photo>> fetchPhotos(http.Client client) async {
  final response =
      // await client.get('https://cloud.iexapis.com/stable/stock/market/batch?symbols=CNPF,ICOL,PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,IEI,TLH,DIA,BSJF,MONY&types=quote,stats&token=');

      await client.get(
          'https://cloud.iexapis.com/stable/stock/market/batch?symbols=PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,PGF,SNLN,DVHL,AUNZ,MDIV,PHB,PFXF,FPE,TIPX,MLN,SDIV,SIPE,SEMF,EMAG,IEMF,EU,BSCM,LEMF,BSCL,BSCK,BSCJ,BSCI,DSUM,BSCF,KBWD,PCEF,BSCG,BSCH,HYEM,ITM,BKLN,PGHY,IBCE,PZT,IJNK,XMPT,THHY,QYLD,IHY,IYLD,SHYD,PRB,DVHI,GOVT,BSJJ,BSJK,RIGS,INY,IBCD,PZA,PFIG,IBCC,BSCE,PVI,MBG,CXA,FWDB,DIV,CHLC,BSJI,FLTR,PWZ,MUAH,IBDD,PICB,IBDB,BSJH,RVNU,BSJG,IBDC,XOVR,BSJE,EBND,PCY,BWX,SJNK,DES,ANGL,BAB,SST,EMCD,CBND,HYD,PLW,SCPB,FLRN,BWZ,KBWY,ELD,IBND,AOK,RWXL,ITR,DON,DGRS,JNK,TZD,EPU,PFF,HYLD,GGOV,ULST,SPHD,HFIN,DGRW,LWC,ALD,LEMB,AGND,ITIP,EMHY,QLTC,TFI,SRLN,HYLS,SHM,GNMA,CEMB,IGOV,MINC,AGZD,FTSL,SPLV,GHYG,ISTB,ENGN,CMBS,GTIP,SCHO,SMMU,QLTA,SCHZ,HSPX,TUZ,GIY,GSY,TFLO,VMBS,CWB,FLOT,STPZ,MUAC,SCHR,BABZ,HYXU,GMTB,MUNI,WIP,MUAD,QLTB,SCHP,GMMB,MUAE,IPE,NYF,BNDX,MUAF,HYMB,TIPZ,CMF,LAG,ILTB,ITE,CLY,VGSH,VGIT,LTPZ,BABS,HYHG,EMCB,DVYL,VGLT,DHS,TLO,VWOB,IGHG,GLCB,RAVI,VCSH,BSV,BND,BIV,ISHG,SDYL,VCIT,SHY,BLV,HYG,VCLT,TENZ,DTN,BIL,AUD,DLN,DTD,FTSD,CAD,STIP,CORP,HYS,HOLD,TRSY,IEF,IBDA,COBO,BOND,MINT,MBB,CSJ,AGG,SUB,EMB,CIU,GVI,MUB,GBF,TIP,AGZ,CFT,LQD,TLT,IEI,TLH,DIA,BSJF,MONY&types=stats,quote&token=token_was_added_here');
  //https://cloud.iexapis.com/v1/stock/market/batch?&types=price&symbols=aapl,fb,tsla&token=YOUR_TOKEN_HERE
  //https://cloud.iexapis.com/v1/stock/market/batch?&types=quote&symbols=aapl,fb,tsla&token=
  // Use the compute function to run parsePhotos in a separate isolate.
  //https://cloud.iexapis.com/stable/stock/market/batch?symbols=CNPF,ICOL,PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,PGF,SNLN,DVHL,AUNZ,MDIV,PHB,PFXF,FPE,TIPX,MLN,SDIV,SIPE,SEMF,EMAG,IEMF,EU,BSCM,LEMF,BSCL,BSCK,BSCJ,BSCI,DSUM,BSCF,KBWD,PCEF,BSCG,BSCH,HYEM,ITM,BKLN,PGHY,IBCE,PZT,IJNK,XMPT,THHY,QYLD,IHY,IYLD,SHYD,PRB,DVHI,GOVT,BSJJ,BSJK,RIGS,INY,IBCD,PZA,PFIG,IBCC,BSCE,PVI,MBG,CXA,FWDB,DIV,CHLC,BSJI,FLTR,PWZ,MUAH,IBDD,PICB,IBDB,BSJH,RVNU,BSJG,IBDC,XOVR,BSJE,EBND,PCY,BWX,SJNK,DES,ANGL,BAB,SST,EMCD,CBND,HYD,PLW,SCPB,FLRN,BWZ,KBWY,ELD,IBND,AOK,RWXL,ITR,DON,DGRS,JNK,TZD,EPU,PFF,HYLD,GGOV,ULST,SPHD,HFIN,DGRW,LWC,ALD,LEMB,AGND,ITIP,EMHY,QLTC,TFI,SRLN,HYLS,SHM,GNMA,CEMB,IGOV,MINC,AGZD,FTSL,SPLV,GHYG,ISTB,ENGN,CMBS,GTIP,SCHO,SMMU,QLTA,SCHZ,HSPX,TUZ,GIY,GSY,TFLO,VMBS,CWB,FLOT,STPZ,MUAC,SCHR,BABZ,HYXU,GMTB,MUNI,WIP,MUAD,QLTB,SCHP,GMMB,MUAE,IPE,NYF,BNDX,MUAF,HYMB,TIPZ,CMF,LAG,ILTB,ITE,CLY,VGSH,VGIT,LTPZ,BABS,HYHG,EMCB,DVYL,VGLT,DHS,TLO,VWOB,IGHG,GLCB,RAVI,VCSH,BSV,BND,BIV,ISHG,SDYL,VCIT,SHY,BLV,HYG,VCLT,TENZ,DTN,BIL,AUD,DLN,DTD,FTSD,CAD,STIP,CORP,HYS,HOLD,TRSY,IEF,IBDA,COBO,BOND,MINT,MBB,CSJ,AGG,SUB,EMB,CIU,GVI,MUB,GBF,TIP,AGZ,CFT,LQD,TLT,IEI,TLH,DIA,BSJF,MONY&types=quote,stats&token=
  return compute(parsePhotos, response.body);
}

// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
  //final parsed = json.decode(responseBody).cast<Map<String,dynamic>>();

  //return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();

  dynamic Obj = json.decode(responseBody);
  debugPrint(responseBody, wrapWidth: 8192);
  print(Obj.length);

  List<Photo> photoList = [];
  Obj.forEach((k, v) => photoList.add(Photo(k, v)));

  return photoList;
}

class Photo {
  String symbol;
  //String companyName;
  dynamic data;
  // dynamic iexClose;
  // dynamic quote;
  Photo(this.symbol, this.data);
}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Monthly Paying ETFs';

    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              child: Text('About'),
              decoration: BoxDecoration(
                color: Colors.grey,
              ),
            ),
            ListTile(
              title: Text(
                  'This app is to provide the list of ETF s that pay monthly dividend'),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: Text('for questions or feedback please contact me at  '),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
      appBar: AppBar(
        title: Text(title),
        backgroundColor: Colors.greenAccent,
      ),
      body: FutureBuilder<List<Photo>>(
        future: fetchPhotos(http.Client()),
        builder: (context, snapshot) {
          if (snapshot.hasError) print(snapshot.error);

          return snapshot.hasData
              ? PhotosList(photos: snapshot.data)
              : Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

class PhotosList extends StatefulWidget {
  final List<Photo> photos;

  PhotosList({Key key, this.photos})
      : assert(photos != null),
        super(key: key);

  @override
  _PhotosListState createState() => _PhotosListState();
}

class _PhotosListState extends State<PhotosList> {
  @override
  Widget build(BuildContext context) {
    return bodyData();
  }

  SingleChildScrollView bodyData() => SingleChildScrollView(
        scrollDirection: Axis.vertical,

        // padding: EdgeInsets.all(0.0),
        //padding: const EdgeInsets.symmetric(
        //  padding: new EdgeInsets.fromLTRB(0.001, .001, 1.0, 1.0),
        padding: EdgeInsets.all(0.05),

        // child: FittedBox(fit:BoxFit.contain,

        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: FittedBox(
              fit: BoxFit.fitHeight,
              child: DataTable(
                  // sortColumnIndex: 1,
                  //  sortAscending: true,

                  columns: <DataColumn>[
                    DataColumn(
                      label: Text("Company"),
                      onSort: (_, __) {
                        setState(() {
                          widget.photos.sort((a, b) => a.data["quote"]
                                  ["companyName"]
                              .compareTo(b.data["quote"]["companyName"]));
                        });
                      },
                    ),
                    DataColumn(
                      label: Text("ttmDivRate"),
                      numeric: true,
                      onSort: (_, __) {
                        setState(() {
                          widget.photos.sort((a, b) => a.data["quote"]
                                  ["ttmDividendRate"]
                              .compareTo(b.data["quote"]["ttmDividendRate"]));
                        });
                      },
                    ),
                    DataColumn(
                      label: Text("Price"),
                      numeric: true,
                      onSort: (_, __) {
                        setState(() {
                          widget.photos.sort((a, b) => a.data["quote"]
                                  ["latestPrice"]
                              .compareTo(b.data["quote"]["latestPrice"]));
                        });
                      },
                    ),
                  ],
                  rows: widget.photos
                      .map(
                        (photo) => DataRow(
                          cells: [
                            DataCell(
                              Text(
                                  '${photo.data["stats"]["companyName"] ?? ""}'),
                            ),

                            DataCell(
                              Text(
                                  '${photo.data["stats"]["ttmDividendRate"] ?? ""}'),
                            ),
//["quote"]["stats"]
                            DataCell(Text(
                                '${photo.data["stats"]["latestPrice"] ?? ""}')),
                          ],
                        ),
                      )
                      .toList())),
        ),
      );
}

【讨论】:

  • 价格列为空。如果我尝试调用 "delayedPrice":11.552," 或 "iexClose":11.04。 它不会在应用程序中打印。
  • 问题似乎与您尝试获取值的方法有关,请使用获取值的结构。或者尝试之前提供的链接来创建 json 模型
  • 我同意。 TY 的洞察力。这就是提出问题的原因。
  • crazy-lazy-cat 对此有何见解?价格列是空的。如果我尝试调用“delayedPrice”:11.552,或“iexClose”:11.04。它不会在应用程序中打印。
【解决方案2】:

在响应中,对于某些公司(或符号),quote 的值为null。

示例(IEMF、欧盟等):

     "IEMF": {
          "stats": {
               "symbol": "IEMF",
               "nextDividendDate": null,
               "nextEarningsDate": null,
               "exDividendDate": null,
               "peRatio": null,
               "beta": null
          },
          "quote": null
     },
     "EU": {
          "stats": {
               "symbol": "EU",
               "nextDividendDate": null,
               "nextEarningsDate": null,
               "exDividendDate": null,
               "peRatio": null,
               "beta": null
          },
          "quote": null
     },

检查:

photo.data["quote"] != null

在quote 中没有stats。所以不要打电话给photo.data["quote"]["stats"]

用Text('${(photo.data["quote"] != null ? photo.data["quote"]["latestPrice"] : "") ?? ""}')代替Text('${photo.data["quote"]["stats"]["latestPrice"] ?? ""}')

完整代码:

import 'dart:async';
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

//import 'package:flutter_web/material.dart';
//import 'package:flutter/main.dart' as app;
//import 'package:flutter_web_ui/ui.dart' as ui;

Future<List<Photo>> fetchPhotos(http.Client client) async {
  final response =
      // await client.get('https://cloud.iexapis.com/stable/stock/market/batch?symbols=CNPF,ICOL,PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,IEI,TLH,DIA,BSJF,MONY&types=quote,stats&token=');
      await client.get(
    'https://cloud.iexapis.com/stable/stock/market/batch?symbols=PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,PGF,SNLN,DVHL,AUNZ,MDIV,PHB,PFXF,FPE,TIPX,MLN,SDIV,SIPE,SEMF,EMAG,IEMF,EU,BSCM,LEMF,BSCL,BSCK,BSCJ,BSCI,DSUM,BSCF,KBWD,PCEF,BSCG,BSCH,HYEM,ITM,BKLN,PGHY,IBCE,PZT,IJNK,XMPT,THHY,QYLD,IHY,IYLD,SHYD,PRB,DVHI,GOVT,BSJJ,BSJK,RIGS,INY,IBCD,PZA,PFIG,IBCC,BSCE,PVI,MBG,CXA,FWDB,DIV,CHLC,BSJI,FLTR,PWZ,MUAH,IBDD,PICB,IBDB,BSJH,RVNU,BSJG,IBDC,XOVR,BSJE,EBND,PCY,BWX,SJNK,DES,ANGL,BAB,SST,EMCD,CBND,HYD,PLW,SCPB,FLRN,BWZ,KBWY,ELD,IBND,AOK,RWXL,ITR,DON,DGRS,JNK,TZD,EPU,PFF,HYLD,GGOV,ULST,SPHD,HFIN,DGRW,LWC,ALD,LEMB,AGND,ITIP,EMHY,QLTC,TFI,SRLN,HYLS,SHM,GNMA,CEMB,IGOV,MINC,AGZD,FTSL,SPLV,GHYG,ISTB,ENGN,CMBS,GTIP,SCHO,SMMU,QLTA,SCHZ,HSPX,TUZ,GIY,GSY,TFLO,VMBS,CWB,FLOT,STPZ,MUAC,SCHR,BABZ,HYXU,GMTB,MUNI,WIP,MUAD,QLTB,SCHP,GMMB,MUAE,IPE,NYF,BNDX,MUAF,HYMB,TIPZ,CMF,LAG,ILTB,ITE,CLY,VGSH,VGIT,LTPZ,BABS,HYHG,EMCB,DVYL,VGLT,DHS,TLO,VWOB,IGHG,GLCB,RAVI,VCSH,BSV,BND,BIV,ISHG,SDYL,VCIT,SHY,BLV,HYG,VCLT,TENZ,DTN,BIL,AUD,DLN,DTD,FTSD,CAD,STIP,CORP,HYS,HOLD,TRSY,IEF,IBDA,COBO,BOND,MINT,MBB,CSJ,AGG,SUB,EMB,CIU,GVI,MUB,GBF,TIP,AGZ,CFT,LQD,TLT,IEI,TLH,DIA,BSJF,MONY&types=stats,quote&token=pk_fd71da12cae34ae9abdf3df4958302fe',
  );
  //https://cloud.iexapis.com/v1/stock/market/batch?&types=price&symbols=aapl,fb,tsla&token=YOUR_TOKEN_HERE
  //https://cloud.iexapis.com/v1/stock/market/batch?&types=quote&symbols=aapl,fb,tsla&token=
  // Use the compute function to run parsePhotos in a separate isolate.
  //https://cloud.iexapis.com/stable/stock/market/batch?symbols=CNPF,ICOL,PGX,MORL,EMLC,GYLD,IPFF,SMB,YDIV,YYY,PEY,PGF,SNLN,DVHL,AUNZ,MDIV,PHB,PFXF,FPE,TIPX,MLN,SDIV,SIPE,SEMF,EMAG,IEMF,EU,BSCM,LEMF,BSCL,BSCK,BSCJ,BSCI,DSUM,BSCF,KBWD,PCEF,BSCG,BSCH,HYEM,ITM,BKLN,PGHY,IBCE,PZT,IJNK,XMPT,THHY,QYLD,IHY,IYLD,SHYD,PRB,DVHI,GOVT,BSJJ,BSJK,RIGS,INY,IBCD,PZA,PFIG,IBCC,BSCE,PVI,MBG,CXA,FWDB,DIV,CHLC,BSJI,FLTR,PWZ,MUAH,IBDD,PICB,IBDB,BSJH,RVNU,BSJG,IBDC,XOVR,BSJE,EBND,PCY,BWX,SJNK,DES,ANGL,BAB,SST,EMCD,CBND,HYD,PLW,SCPB,FLRN,BWZ,KBWY,ELD,IBND,AOK,RWXL,ITR,DON,DGRS,JNK,TZD,EPU,PFF,HYLD,GGOV,ULST,SPHD,HFIN,DGRW,LWC,ALD,LEMB,AGND,ITIP,EMHY,QLTC,TFI,SRLN,HYLS,SHM,GNMA,CEMB,IGOV,MINC,AGZD,FTSL,SPLV,GHYG,ISTB,ENGN,CMBS,GTIP,SCHO,SMMU,QLTA,SCHZ,HSPX,TUZ,GIY,GSY,TFLO,VMBS,CWB,FLOT,STPZ,MUAC,SCHR,BABZ,HYXU,GMTB,MUNI,WIP,MUAD,QLTB,SCHP,GMMB,MUAE,IPE,NYF,BNDX,MUAF,HYMB,TIPZ,CMF,LAG,ILTB,ITE,CLY,VGSH,VGIT,LTPZ,BABS,HYHG,EMCB,DVYL,VGLT,DHS,TLO,VWOB,IGHG,GLCB,RAVI,VCSH,BSV,BND,BIV,ISHG,SDYL,VCIT,SHY,BLV,HYG,VCLT,TENZ,DTN,BIL,AUD,DLN,DTD,FTSD,CAD,STIP,CORP,HYS,HOLD,TRSY,IEF,IBDA,COBO,BOND,MINT,MBB,CSJ,AGG,SUB,EMB,CIU,GVI,MUB,GBF,TIP,AGZ,CFT,LQD,TLT,IEI,TLH,DIA,BSJF,MONY&types=quote,stats&token=
  return compute(parsePhotos, response.body);
}

// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
  //final parsed = json.decode(responseBody).cast<Map<String,dynamic>>();

  //return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();

  dynamic obj = json.decode(responseBody);
  debugPrint(responseBody, wrapWidth: 1000);
  print(obj.length);

  List<Photo> photoList = [];
  obj.forEach((k, v) => photoList.add(Photo(k, v)));

  return photoList;
}

class Photo {
  String symbol;

  //String companyName;
  dynamic data;

  // dynamic iexClose;
  // dynamic quote;
  Photo(this.symbol, this.data);
}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Monthly Paying ETFs';

    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              child: Text('About'),
              decoration: BoxDecoration(
                color: Colors.grey,
              ),
            ),
            ListTile(
              title: Text(
                'This app is to provide the list of ETF s that pay monthly dividend',
              ),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
            ListTile(
              title: Text(
                'for questions or feedback please contact me at  ',
              ),
              onTap: () {
                // Update the state of the app
                // ...
                // Then close the drawer
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
      appBar: AppBar(
        title: Text(title),
        backgroundColor: Colors.greenAccent,
      ),
      body: FutureBuilder<List<Photo>>(
        future: fetchPhotos(http.Client()),
        builder: (context, snapshot) {
          if (snapshot.hasError) print(snapshot.error);

          return snapshot.hasData
              ? PhotosList(photos: snapshot.data)
              : Center(
                  child: CircularProgressIndicator(),
                );
        },
      ),
    );
  }
}

class PhotosList extends StatefulWidget {
  final List photos;

  PhotosList({Key key, this.photos})
      : assert(photos != null),
        super(key: key);

  @override
  _PhotosListState createState() => _PhotosListState();
}

class _PhotosListState extends State<PhotosList> {
  @override
  Widget build(BuildContext context) {
    return bodyData();
  }

  SingleChildScrollView bodyData() => SingleChildScrollView(
        scrollDirection: Axis.vertical,

        // padding: EdgeInsets.all(0.0),
        //padding: const EdgeInsets.symmetric(
        //  padding: new EdgeInsets.fromLTRB(0.001, .001, 1.0, 1.0),
        padding: EdgeInsets.all(0.05),

        // child: FittedBox(fit:BoxFit.contain,

        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: FittedBox(
            fit: BoxFit.fitHeight,
            child: DataTable(
              // sortColumnIndex: 1,
              //  sortAscending: true,

              columns: <DataColumn>[
                DataColumn(
                  label: Text("Company"),
                  onSort: (_, __) {
                    setState(() {
                      widget.photos.sort((a, b) => a.data["quote"]
                              ["companyName"]
                          .compareTo(b.data["quote"]["companyName"]));
                    });
                  },
                ),
                DataColumn(
                  label: Text("ttmDivRate"),
                  numeric: true,
                  onSort: (_, __) {
                    setState(() {
                      widget.photos.sort((a, b) => a.data["quote"]
                              ["ttmDividendRate"]
                          .compareTo(b.data["quote"]["ttmDividendRate"]));
                    });
                  },
                ),
                DataColumn(
                  label: Text("Price"),
                  numeric: true,
                  onSort: (_, __) {
                    setState(() {
                      widget.photos.sort((a, b) => a.data["quote"]
                              ["latestPrice"]
                          .compareTo(b.data["quote"]["latestPrice"]));
                    });
                  },
                ),
              ],
              rows: widget.photos
                  .map(
                    (photo) => DataRow(
                      cells: [
                        DataCell(
                          Text(
                            '${photo.data["stats"]["companyName"] ?? ""}',
                          ),
                        ),

                        DataCell(
                          Text(
                            '${photo.data["stats"]["ttmDividendRate"] ?? ""}',
                          ),
                        ),
//["quote"]["stats"]
                        DataCell(
                          Text(
                            '${(photo.data["quote"] != null ? photo.data["quote"]["latestPrice"] : "") ?? ""}',
                          ),
                        ),
                      ],
                    ),
                  )
                  .toList(),
            ),
          ),
        ),
      );
}

【讨论】:

    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 2021-08-26
    • 2020-12-06
    相关资源
    最近更新 更多