未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”(json 解析)

Posted

技术标签:

【中文标题】未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”(json 解析)【英文标题】:Unhandled Exception: NoSuchMethodError: The method '[]' was called on null (json parse) 【发布时间】:2020-07-11 23:41:57 【问题描述】:

我正在尝试解析这个打印“已确认”的 json


  "Delhi": 
    "districtData": 
      "East Delhi": 
        "confirmed": 1,
        "lastupdatedtime": ""
      ,
      "South West Delhi": 
        "confirmed": 3,
        "lastupdatedtime": ""
      ,
      "West Delhi": 
        "confirmed": 2,
        "lastupdatedtime": ""
      ,
      "North Delhi": 
        "confirmed": 3,
        "lastupdatedtime": ""
      ,
      "New Delhi": 
        "confirmed": 3,
        "lastupdatedtime": ""
      ,
      "South Delhi": 
        "confirmed": 2,
        "lastupdatedtime": ""
      ,
      "North East Delhi": 
        "confirmed": 1,
        "lastupdatedtime": ""
      ,
      "North West Delhi": 
        "confirmed": 3,
        "lastupdatedtime": ""
      ,
      "Unknown": 
        "confirmed": 53,
        "lastupdatedtime": ""
      ,
      "Delhi": 
        "confirmed": 1,
        "lastupdatedtime": ""
      
    
  

https://api.covid19india.org/state_district_wise.json 是实际的 json 数据 并且只反序列化德里数据,因为我想测试它是对还是错。就像

class IndiaState 
  Delhi delhi;

  IndiaState(
    this.delhi,
  );

  factory IndiaState.fromJson(Map<String, dynamic> json) => IndiaState(
    delhi: Delhi.fromJson(json["Delhi"]),
  );


class Delhi 
  DelhiDistrictData districtData;

  Delhi(
    this.districtData,
  );

  factory Delhi.fromJson(Map<String, dynamic> json) => Delhi(
    districtData: DelhiDistrictData.fromJson(json["districtData"]),
  );


class DelhiDistrictData 
  DelhiValue eastDelhi;
  DelhiValue southWestDelhi;
  DelhiValue westDelhi;
  DelhiValue delhi;
  DelhiValue southDelhi;
  DelhiValue northEastDelhi;
  DelhiValue northDelhi;
  DelhiValue northWestDelhi;
  DelhiValue unknown;
  DelhiValue newDelhi;

  DelhiDistrictData(
    this.eastDelhi,
    this.southWestDelhi,
    this.westDelhi,
    this.delhi,
    this.southDelhi,
    this.northEastDelhi,
    this.northDelhi,
    this.northWestDelhi,
    this.unknown,
    this.newDelhi,
  );

  factory DelhiDistrictData.fromJson(Map<String, dynamic> json) => DelhiDistrictData(
    eastDelhi: DelhiValue.fromJson(json["East Delhi"]),
    southWestDelhi: DelhiValue.fromJson(json["South West Delhi"]),
    westDelhi: DelhiValue.fromJson(json["West Delhi"]),
    delhi: DelhiValue.fromJson(json["Delhi"]),
    southDelhi: DelhiValue.fromJson(json["South Delhi"]),
    northEastDelhi: DelhiValue.fromJson(json["North East Delhi"]),
    northDelhi: DelhiValue.fromJson(json["North Delhi"]),
    northWestDelhi: DelhiValue.fromJson(json["North West Delhi"]),
    newDelhi: DelhiValue.fromJson(json["New Delhi"]),
    unknown: DelhiValue.fromJson(json["Unknown"]),
  );


class DelhiValue 
  int confirmed;
  String lastupdatedtime;


  DelhiValue(
    this.confirmed,
    this.lastupdatedtime,
  );

  factory DelhiValue.fromJson(Map<String, dynamic> json) => DelhiValue(
    confirmed: json['confirmed'],
    lastupdatedtime: json["lastupdatedtime"],
  );

现在我正在尝试将确认结果打印为德里的任何一个地区

  @override
  void initState() 
    // TODO: implement initState
    setState(() 
      isLoading = true;
    );

    givenFunction();

    setState(() 
      isLoading = false;
    );
  

  Future givenFunction() async 
    final httpRequest = await http.get(districtAPI);
    final json = jsonDecode(httpRequest.body);
    IndiaState firstObject = new IndiaState.fromJson(json);
    print(firstObject.delhi.districtData.eastDelhi.confirmed.toString());
  

当我尝试打印 eastDelhi 确认数据时出现错误

E/flutter ( 5895): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
E/flutter ( 5895): Receiver: null
E/flutter ( 5895): Tried calling: []("confirmed")
E/flutter ( 5895): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter ( 5895): #1      new DelhiValue.fromJson (package:coraona2903/models/district_state.dart:77:20)
E/flutter ( 5895): #2      new DelhiDistrictData.fromJson (package:coraona2903/models/district_state.dart:54:23)
E/flutter ( 5895): #3      new Delhi.fromJson (package:coraona2903/models/district_state.dart:21:37)
E/flutter ( 5895): #4      new IndiaState.fromJson (package:coraona2903/models/district_state.dart:9:18)
E/flutter ( 5895): #5      Covid19ScreenState.givenFunction (package:coraona2903/screens/covid_19_screen.dart:37:34)
E/flutter ( 5895): <asynchronous suspension>

【问题讨论】:

如果打印整个对象会得到什么?因为对象的那部分显然是空的。 【参考方案1】:

只需检查修改后的代码:

以下是您提供的本地 json:


    "Delhi": 
      "districtData": 
        "East Delhi": 
          "confirmed": 1,
          "lastupdatedtime": ""
        ,
        "South West Delhi": 
          "confirmed": 3,
          "lastupdatedtime": ""
        ,
        "West Delhi": 
          "confirmed": 2,
          "lastupdatedtime": ""
        ,
        "North Delhi": 
          "confirmed": 3,
          "lastupdatedtime": ""
        ,
        "New Delhi": 
          "confirmed": 3,
          "lastupdatedtime": ""
        ,
        "South Delhi": 
          "confirmed": 2,
          "lastupdatedtime": ""
        ,
        "North East Delhi": 
          "confirmed": 1,
          "lastupdatedtime": ""
        ,
        "North West Delhi": 
          "confirmed": 3,
          "lastupdatedtime": ""
        ,
        "Unknown": 
          "confirmed": 53,
          "lastupdatedtime": ""
        ,
        "Delhi": 
          "confirmed": 1,
          "lastupdatedtime": ""
        
      
    
  

后来我为此创建了一个模型类:

// To parse this JSON data, do
//
//     final indiaState = indiaStateFromJson(jsonString);

import 'dart:convert';

IndiaState indiaStateFromJson(String str) => IndiaState.fromJson(json.decode(str));

String indiaStateToJson(IndiaState data) => json.encode(data.toJson());

class IndiaState 
    Delhi delhi;

    IndiaState(
        this.delhi,
    );

    factory IndiaState.fromJson(Map<String, dynamic> json) => IndiaState(
        delhi: Delhi.fromJson(json["Delhi"]),
    );

    Map<String, dynamic> toJson() => 
        "Delhi": delhi.toJson(),
    ;


class Delhi 
    Map<String, DistrictDatum> districtData;

    Delhi(
        this.districtData,
    );

    factory Delhi.fromJson(Map<String, dynamic> json) => Delhi(
        districtData: Map.from(json["districtData"]).map((k, v) => MapEntry<String, DistrictDatum>(k, DistrictDatum.fromJson(v))),
    );

    Map<String, dynamic> toJson() => 
        "districtData": Map.from(districtData).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
    ;


class DistrictDatum 
    int confirmed;
    String lastupdatedtime;

    DistrictDatum(
        this.confirmed,
        this.lastupdatedtime,
    );

    factory DistrictDatum.fromJson(Map<String, dynamic> json) => DistrictDatum(
        confirmed: json["confirmed"],
        lastupdatedtime: json["lastupdatedtime"],
    );

    Map<String, dynamic> toJson() => 
        "confirmed": confirmed,
        "lastupdatedtime": lastupdatedtime,
    ;

以下是我在列表视图中显示您的数据的主要文件,请查看:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sample_project_for_api/model.dart';

class HomePage extends StatefulWidget 
  @override
  _HomePageState createState() => _HomePageState();


class _HomePageState extends State<HomePage> 
  bool isLoading = false;
  List<Cities> citilesList = List();

  // here i have taken the  json locally which you posted on stack 
  Future<String> loadFromAssets() async 
    return await rootBundle.loadString('json/parse.json');
  

  @override
  void initState() 
    super.initState();
    givenFunction();
  

  Future givenFunction() async 
    setState(() 
      isLoading = true;
    );

    //final httpRequest = await http.get(districtAPI);
    //final json = jsonDecode(httpRequest.body);
    // you can make the http call above just uncomment is and comment the below line
    String jsonString = await loadFromAssets();
    // Here you can just replace down your httpRequest.body with jsonString
    final indiaState = indiaStateFromJson(jsonString);
    indiaState.delhi.districtData.forEach((key, value) 
      // This column is show you the values are getting fetched and printed below
      print('This is the key : ' + key);
      print('Confirmed :' + value.confirmed.toString());
      citilesList.add(Cities(key, value.confirmed));
    );
    setState(() 
      isLoading = false;
    );
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: isLoading
            ? CircularProgressIndicator()
            : ListView.builder(
                itemCount: citilesList.length,
                itemBuilder: (BuildContext context, int index) 
                  return Container(
                    child: Card(
                      margin:
                          EdgeInsets.symmetric(vertical: 10, horizontal: 10),
                      child: Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: Row(
                          children: <Widget>[
                            Text(citilesList[index].state + ": "),
                            Text(citilesList[index].confirmed.toString())
                          ],
                        ),
                      ),
                    ),
                  );
                ,
              ),
      ),
    );
  


void main() 
  runApp(HomePage());


class Cities 
  final String state;
  final int confirmed;

  Cities(this.state, this.confirmed);


刚刚为数据获取项添加了一个示例图像: 让我知道它是否有效

【讨论】:

实际上你能写一份打印声明吗,因为我很难理解它。您可以查看我的打印声明。 只需查看代码,我已经以您的示例为您创建了一个示例。 如果您能帮我找出解析中的错误,那就太好了,因为我无法理解我的反序列化出了什么问题。 刚刚检查了你的模型类,所以它没有给出任何错误,但它每次只给出一个对象,并且你已经创建了 DelhiDistrictData 类,因此,如果有动态键值对从您必须每次修改模型类的 JSON。因此,只需检查我的模型类,我在其中创建了一个地图条目,其中我使用键作为 distname,值作为 DistrictDatum 对象。

以上是关于未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”(json 解析)的主要内容,如果未能解决你的问题,请参考以下文章

获取“未处理的异常:NoSuchMethodError:方法'map'在null上被调用”

未处理的异常:NoSuchMethodError:方法“findAncestorStateOfType”在 null 上被调用

Flutter,无法提取 api 数据:(未处理的异常:NoSuchMethodError:方法 'map' 在 null 上被调用。)

未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”(json 解析)

未处理的异常:NoSuchMethodError:在 null 上调用了方法“toRawHandle”

未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”。尝试调用:[](“is_ordered”)。检查空字段 Firebase [重复]