【问题标题】:NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'map' with matching arguments. (Flutter)NoSuchMethodError:类 '_InternalLinkedHashMap<String, dynamic>' 没有具有匹配参数的实例方法 'map'。 (扑)
【发布时间】:2021-02-26 16:53:03
【问题描述】:

我是编程世界的新手,我从许多来源对这个错误进行了研究,但我什么也没找到。我正在尝试在 Flutter 中构建一个 ListView.builder,其中 itemBuilder 来自我的 JSON 响应数据,如下所示:

{
  "status": "success",
  "data": {
    "general": [
      {
        "id": 1,
        "name": "Sumbangan Pembinaan Pendidikan",
        "icon": "credit_card",
        "type": "monthly",
        "amount": 125000
      },
      {
        "id": 2,
        "name": "Uang Bangunan",
        "icon": "credit_card",
        "type": "yearly",
        "amount": 1250000
      }
    ],
    "categorized": [
      {
        "name": "Bayar Buku",
        "icon": "credit_card",
        "childs": [
          {
            "id": 3,
            "name": "Buku 1",
            "icon": "credit_card",
            "type": "monthly",
            "amount": 324423
          },
          {
            "id": 4,
            "name": "Buku 2",
            "icon": "credit_card",
            "type": "monthly",
            "amount": 16000
          }
        ]
      }
    ]
  }
}

我需要使用我的 ListView.builder 获取要获取的项目的“名称”,这就是我想出的

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:sekolah_kita/components/constant.dart';
import 'package:http/http.dart' as http;
import 'package:sekolah_kita/components/storage.dart';

class DaftarTransaksi extends StatefulWidget {
  @override
  _DaftarTransaksiState createState() => _DaftarTransaksiState();
}

class _DaftarTransaksiState extends State<DaftarTransaksi> {
  final SecureStorage secureStorage = SecureStorage();

  List studentFeesData;

  bool isLoading = true;

  @override
  void initState() {
    secureStorage.readSecureData('student_token').then((value) {
      getStudentFees(
        value,
      );
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: secondaryColor,
      appBar: AppBar(
        leading: IconButton(
          onPressed: (){
            Navigator.pop(context);
          },
          icon: Icon(
            Icons.arrow_back
          ),
        ),
        backgroundColor: primaryColor,
        elevation: 0,
        centerTitle: true,
        title: Text(
          'Transaksi',
          style: TextStyle(
            fontSize: screenWidth(context)*(1/25),
          ),
        ),
      ),
      body: isLoading ? Center(
        child: CircularProgressIndicator(
          backgroundColor: primaryColor,
        ),
      ) : Center(
        child: Container(
          margin: EdgeInsets.symmetric(
            vertical: screenHeight(context)*(1/30),
            horizontal: screenWidth(context)*(1/20),
          ),
          color: Colors.green.withOpacity(0.5),
          child: ListView.builder(
            itemCount: studentFeesData == 0 ? 0 : studentFeesData.length,
            itemBuilder: (context, index){
              return studentFeeButtonMenu(
                context, 
                studentFeesData[index]['data']['general']['name'], 
                Icons.credit_card);
            },
          ),
        ),
      ),
    );
  }

  Future<String> getStudentFees(String token) async{
    var uri = Uri.https('sekolahkita.zonaku.com', '/api/school-fee/bill');
    http.Response response = await http.get(
      uri,
      headers: {
        HttpHeaders.contentTypeHeader: 'application/json',
        HttpHeaders.acceptHeader: 'application/json',
        HttpHeaders.authorizationHeader: "Bearer "+token,
      },
    );
    var data = json.decode(response.body);
    studentFeesData = List<dynamic>.from(
      data.map<dynamic>(
        (dynamic item) => item,
      )
    );
  }

  Widget studentFeeButtonMenu(BuildContext context, String text, IconData iconFee){
    return Container(
      width: double.infinity,
      height: screenHeight(context)*(1/12),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(10),
      ),
      child: Center(
        child: Container(
          width: screenWidth(context)*(1/1.3),
          height: double.infinity,
          color: Colors.red,
          child: Row(
            children: [
              Icon(
                iconFee,
                color: Color(0xff84923f),
              ),
              SizedBox(
                width: screenWidth(context)*(1/10),
              ),
              Text(
                text,
                style: TextStyle(
                  color: Colors.black,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

}

但我总是在 ListView.builder 中显示我想要的内容时出错。我的 JSON 响应的运行时类型是 '_InternalLinkedHashMap',我知道我需要将其转换为 List,因此它可以配备 studentFeesData 变量以在 ListView.builder 中显示。

这是我的错误信息:

发生了异常。 NoSuchMethodError (NoSuchMethodError: Class '_InternalLinkedHashMap' 没有具有匹配参数的实例方法 'map'。 接收者:_LinkedHashMap len:2 尝试调用:map(Closure: (dynamic) => dynamic) 找到:map((K, V) => MapEntry) => Map)

我希望任何人都可以帮助我。

【问题讨论】:

    标签: android json list flutter listview


    【解决方案1】:

    您需要将json 数据转换为模型对象以便于访问。 我已将您的json 数据转换如下:

    StudentFeesModel
    GeneralModel
    CategorizedModel
    

    现在,您可以访问和遍历GeneralModelCategorizedModel 的列表以获取children 的名称。

    这里是sn-p:

    import 'dart:convert';
    
    void main() {
      dynamic data = {
        "status": "success",
        "data": {
          "general": [
            {
              "id": 1,
              "name": "Sumbangan Pembinaan Pendidikan",
              "icon": "credit_card",
              "type": "monthly",
              "amount": 125000
            },
            {
              "id": 2,
              "name": "Uang Bangunan",
              "icon": "credit_card",
              "type": "yearly",
              "amount": 1250000
            }
          ],
          "categorized": [
            {
              "name": "Bayar Buku",
              "icon": "credit_card",
              "childs": [
                {
                  "id": 3,
                  "name": "Buku 1",
                  "icon": "credit_card",
                  "type": "monthly",
                  "amount": 324423
                },
                {
                  "id": 4,
                  "name": "Buku 2",
                  "icon": "credit_card",
                  "type": "monthly",
                  "amount": 16000
                }
              ]
            }
          ]
        }
      };
    
      // NOTE: You just need to pass data instead of data["data"] i.e,
      // You should write the following:
      // StudentFeesModel studentFeesData = StudentFeesModel.fromJson(data);
      StudentFeesModel studentFeesData = StudentFeesModel.fromJson(data["data"]);
      
      List generalNames = studentFeesData.general.map((generalModel) => generalModel.name).toList();
      List categorizedNames = studentFeesData.categorized.map((categorizedModel) => categorizedModel.name).toList();
      
      print("General names: " + generalNames.toString());
      print("Categorized names: " + categorizedNames.toString());
      
      // If you want categorized child names, then
      // Iterate over all categorized objects & add all child names to a single list
      
      List categorizedChildNames = [];
      for(dynamic categorized in studentFeesData.categorized) {
        categorizedChildNames.addAll(categorized.childs.map((childObject) => childObject.name).toList());
      }
      
      print("Categorized child names: " + categorizedChildNames.toString());
    }
    
    // **************************
    // Model classes
    // **************************
    class StudentFeesModel {
      StudentFeesModel({
        this.general,
        this.categorized,
      });
    
      final List<dynamic> general, categorized;
    
      factory StudentFeesModel.fromJson(dynamic json) {
        return StudentFeesModel(
          general: GeneralModel.listOfGeneralModel(json["general"]),
          categorized: CategorizedModel.listOfCategorizedModel(json["categorized"]),
        );
      }
      
      dynamic toJson() => {
        "general": general,
        "categorized": categorized,
      };
      
      @override
      String toString() {
        return '${JsonEncoder.withIndent(' ').convert(this)}';
      }
    }
    
    class GeneralModel {
      GeneralModel({
        this.id,
        this.name,
        this.icon,
        this.type,
        this.amount,
      });
    
      final int id, amount;
      final String name, icon, type;
    
      factory GeneralModel.fromJson(dynamic json) {
        if (json == null) return null;
    
        return GeneralModel(
          id: json["id"],
          name: json["name"],
          icon: json["icon"],
          type: json["type"],
          amount: json["amount"],
        );
      }
    
      static List<dynamic> listOfGeneralModel(dynamic list) {
        if (list == null) return null;
    
        dynamic generalModelList = [];
        for (dynamic json in list) {
          generalModelList.add(GeneralModel.fromJson(json));
        }
    
        return generalModelList;
      }
      
      dynamic toJson() => {
        "id": id,
        "name": name,
        "icon": icon,
        "type": type,
        "amount": amount,
      };
      
      @override
      String toString() {
        return '${JsonEncoder.withIndent(' ').convert(this)}';
      }
    }
    
    class CategorizedModel {
      CategorizedModel({
        this.name,
        this.icon,
        this.childs, // children would be more appropriate
      });
    
      final String name, icon;
      final List<dynamic> childs; // children would be more appropriate
    
      factory CategorizedModel.fromJson(dynamic json) {
        return CategorizedModel(
          name: json["name"],
          icon: json["icon"],
          childs: GeneralModel.listOfGeneralModel(json["childs"]), // children would be more appropriate
        );
      }
    
      static List<dynamic> listOfCategorizedModel(List<dynamic> list) {
        if (list == null) return null;
    
        List categorizedModelList = [];
        for (dynamic json in list) {
          categorizedModelList.add(CategorizedModel.fromJson(json));
        }
        
        return categorizedModelList;
      }
      
      dynamic toJson() => {
        "name": name,
        "icon": icon,
        "childs": childs,
      };
      
      @override
      String toString() {
        return '${JsonEncoder.withIndent(' ').convert(this)}';
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-24
      • 1970-01-01
      • 2021-11-07
      • 2019-11-20
      • 2020-04-27
      • 2020-12-19
      • 2020-12-20
      • 2021-10-17
      相关资源
      最近更新 更多