簡體   English   中英

_TypeError(類型&#39;_InternalLinkedHashMap<String, dynamic> &#39; 不是類型 &#39;List 的子類型<dynamic> &#39;) 錯誤

[英]_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>') ERROR

我正在嘗試遵循有關制作數據模型、實現 GET 請求並顯示我的數據的教程。 我嘗試使用的 api 以包含鍵值對的對象開頭。 教程 api 沒有。 我需要知道如何按照我嘗試的方式進行操作,因為我遇到的許多 api 都是以這種方式構建的。 這是我得到的錯誤。

在此處輸入圖像描述

這是我的 GET 請求的代碼:

import 'dart:convert';
import 'package:ffxiv_job_viewer/models/job_list_model.dart';
import 'package:ffxiv_job_viewer/utils/app_constants.dart';
import 'package:http/http.dart' as http;

class ApiService {
  Future<List<JobList>> getAllJobs() async {
    final allJobsUrl =
        Uri.parse(AppConstants.BASE_URL + AppConstants.JOB_LIST_URI);
    final response = await http.get(allJobsUrl);
    List<JobList> allJobs = [];
    List body = json.decode(response.body);
    body.forEach((job) {
      allJobs.add(JobList.fromJson(job));
    });
    print(response.statusCode);
    print(response.body);
    return allJobs;
  }
 }

這是我的模型文件的代碼:

import 'dart:convert';

JobList jobListFromJson(String str) => JobList.fromJson(json.decode(str));

String jobListToJson(JobList data) => json.encode(data.toJson());

class JobList {
    JobList({
        required this.results,
    });

    List<Result> results;

    factory JobList.fromJson(Map<String, dynamic> json) => JobList(
        results: List<Result>.from(json["Results"].map((x) => Result.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "Results": List<dynamic>.from(results.map((x) => x.toJson())),
    };
}

class Result {
    Result({
        required this.id,
        required this.icon,
        required this.name,
        required this.url,
    });

    int id;
    String icon;
    String name;
    String url;

    factory Result.fromJson(Map<String, dynamic> json) => Result(
        id: json["ID"],
        icon: json["Icon"],
        name: json["Name"],
        url: json["Url"],
    );

    Map<String, dynamic> toJson() => {
        "ID": id,
        "Icon": icon,
        "Name": name,
        "Url": url,
    };
}

您不能將 jsonDecode() 作為 Map<String, dynamic> 在動態列表中返回。 嘗試將您的動態列表更改為 List<Map<String, dynamic>>

import 'dart:convert';
import 'package:ffxiv_job_viewer/models/job_list_model.dart';
import 'package:ffxiv_job_viewer/utils/app_constants.dart';
import 'package:http/http.dart' as http;

class ApiService {
  Future<List<JobList>> getAllJobs() async {
    final allJobsUrl =
        Uri.parse(AppConstants.BASE_URL + AppConstants.JOB_LIST_URI);
    final response = await http.get(allJobsUrl);
    List<JobList> allJobs = [];
    Map<String, dynamic> body = json.decode(response.body); // Make a change here.
    body['Results'].forEach((job) {
      allJobs.add(JobList.fromJson(job));
    });
    print(response.statusCode);
    print(response.body);
    return allJobs;
  }
 }

json.decode()返回Map<String, dynamic>實例而不是List 您發送請求的服務器可能會發回一個 JSON,該 JSON 需要解碼為Map<String, dynamic>以在您的移動應用程序中使用。

編輯 :

您提供的 URL 會返回此響應:

{
"Pagination": {
    "Page": 1,
    "PageNext": null,
    "PagePrev": null,
    "PageTotal": 1,
    "Results": 40,
    "ResultsPerPage": 100,
    "ResultsTotal": 40
},
"Results": [
    {
        "ID": 1,
        "Icon": "/cj/1/gladiator.png",
        "Name": "gladiator",
        "Url": "/ClassJob/1"
    },
    {
        "ID": 2,
        "Icon": "/cj/1/pugilist.png",
        "Name": "pugilist",
        "Url": "/ClassJob/2"
    },
    {
        "ID": 3,
        "Icon": "/cj/1/marauder.png",
        "Name": "marauder",
        "Url": "/ClassJob/3"
    },
    {
        "ID": 4,
        "Icon": "/cj/1/lancer.png",
        "Name": "lancer",
        "Url": "/ClassJob/4"
    },
    {
        "ID": 5,
        "Icon": "/cj/1/archer.png",
        "Name": "archer",
        "Url": "/ClassJob/5"
    },
    {
        "ID": 6,
        "Icon": "/cj/1/conjurer.png",
        "Name": "conjurer",
        "Url": "/ClassJob/6"
    },
    {
        "ID": 7,
        "Icon": "/cj/1/thaumaturge.png",
        "Name": "thaumaturge",
        "Url": "/ClassJob/7"
    },
    {
        "ID": 8,
        "Icon": "/cj/1/carpenter.png",
        "Name": "carpenter",
        "Url": "/ClassJob/8"
    },
    {
        "ID": 9,
        "Icon": "/cj/1/blacksmith.png",
        "Name": "blacksmith",
        "Url": "/ClassJob/9"
    },
    {
        "ID": 10,
        "Icon": "/cj/1/armorer.png",
        "Name": "armorer",
        "Url": "/ClassJob/10"
    },
    {
        "ID": 11,
        "Icon": "/cj/1/goldsmith.png",
        "Name": "goldsmith",
        "Url": "/ClassJob/11"
    },
    {
        "ID": 12,
        "Icon": "/cj/1/leatherworker.png",
        "Name": "leatherworker",
        "Url": "/ClassJob/12"
    },
    {
        "ID": 13,
        "Icon": "/cj/1/weaver.png",
        "Name": "weaver",
        "Url": "/ClassJob/13"
    },
    {
        "ID": 14,
        "Icon": "/cj/1/alchemist.png",
        "Name": "alchemist",
        "Url": "/ClassJob/14"
    },
    {
        "ID": 15,
        "Icon": "/cj/1/culinarian.png",
        "Name": "culinarian",
        "Url": "/ClassJob/15"
    },
    {
        "ID": 16,
        "Icon": "/cj/1/miner.png",
        "Name": "miner",
        "Url": "/ClassJob/16"
    },
    {
        "ID": 17,
        "Icon": "/cj/1/botanist.png",
        "Name": "botanist",
        "Url": "/ClassJob/17"
    },
    {
        "ID": 18,
        "Icon": "/cj/1/fisher.png",
        "Name": "fisher",
        "Url": "/ClassJob/18"
    },
    {
        "ID": 19,
        "Icon": "/cj/1/paladin.png",
        "Name": "paladin",
        "Url": "/ClassJob/19"
    },
    {
        "ID": 20,
        "Icon": "/cj/1/monk.png",
        "Name": "monk",
        "Url": "/ClassJob/20"
    },
    {
        "ID": 21,
        "Icon": "/cj/1/warrior.png",
        "Name": "warrior",
        "Url": "/ClassJob/21"
    },
    {
        "ID": 22,
        "Icon": "/cj/1/dragoon.png",
        "Name": "dragoon",
        "Url": "/ClassJob/22"
    },
    {
        "ID": 23,
        "Icon": "/cj/1/bard.png",
        "Name": "bard",
        "Url": "/ClassJob/23"
    },
    {
        "ID": 24,
        "Icon": "/cj/1/whitemage.png",
        "Name": "white mage",
        "Url": "/ClassJob/24"
    },
    {
        "ID": 25,
        "Icon": "/cj/1/blackmage.png",
        "Name": "black mage",
        "Url": "/ClassJob/25"
    },
    {
        "ID": 26,
        "Icon": "/cj/1/arcanist.png",
        "Name": "arcanist",
        "Url": "/ClassJob/26"
    },
    {
        "ID": 27,
        "Icon": "/cj/1/summoner.png",
        "Name": "summoner",
        "Url": "/ClassJob/27"
    },
    {
        "ID": 28,
        "Icon": "/cj/1/scholar.png",
        "Name": "scholar",
        "Url": "/ClassJob/28"
    },
    {
        "ID": 29,
        "Icon": "/cj/1/rogue.png",
        "Name": "rogue",
        "Url": "/ClassJob/29"
    },
    {
        "ID": 30,
        "Icon": "/cj/1/ninja.png",
        "Name": "ninja",
        "Url": "/ClassJob/30"
    },
    {
        "ID": 31,
        "Icon": "/cj/1/machinist.png",
        "Name": "machinist",
        "Url": "/ClassJob/31"
    },
    {
        "ID": 32,
        "Icon": "/cj/1/darkknight.png",
        "Name": "dark knight",
        "Url": "/ClassJob/32"
    },
    {
        "ID": 33,
        "Icon": "/cj/1/astrologian.png",
        "Name": "astrologian",
        "Url": "/ClassJob/33"
    },
    {
        "ID": 34,
        "Icon": "/cj/1/samurai.png",
        "Name": "samurai",
        "Url": "/ClassJob/34"
    },
    {
        "ID": 35,
        "Icon": "/cj/1/redmage.png",
        "Name": "red mage",
        "Url": "/ClassJob/35"
    },
    {
        "ID": 36,
        "Icon": "/cj/1/bluemage.png",
        "Name": "blue mage",
        "Url": "/ClassJob/36"
    },
    {
        "ID": 37,
        "Icon": "/cj/1/gunbreaker.png",
        "Name": "gunbreaker",
        "Url": "/ClassJob/37"
    },
    {
        "ID": 38,
        "Icon": "/cj/1/dancer.png",
        "Name": "dancer",
        "Url": "/ClassJob/38"
    },
    {
        "ID": 39,
        "Icon": "/cj/1/reaper.png",
        "Name": "reaper",
        "Url": "/ClassJob/39"
    },
    {
        "ID": 40,
        "Icon": "/cj/1/sage.png",
        "Name": "sage",
        "Url": "/ClassJob/40"
    }
]
}

所以客戶端應該解碼響應,並從Results鍵中提取你需要的數據

import 'dart:convert';
import 'package:ffxiv_job_viewer/models/job_list_model.dart';
import 'package:ffxiv_job_viewer/utils/app_constants.dart';
import 'package:http/http.dart' as http;

class ApiService {
  Future<List<JobList>> getAllJobs() async {
    final allJobsUrl =
        Uri.parse(AppConstants.BASE_URL + AppConstants.JOB_LIST_URI);
    final response = await http.get(allJobsUrl);
    List<JobList> allJobs = [];
    Map<String, dynamic> body = json.decode(response.body);
    body['Results'].forEach((job) {
      allJobs.add(JobList.fromJson(job));
    });
    print(response.statusCode);
    print(response.body);
    return allJobs;
  }
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM