我正在嘗試從第三方 API( https://randomuser.me/api/?results=50)獲取資料并遇到以下錯誤:
E/flutter (18902): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
E/flutter (18902): #0 ProfileProvider.fetchData.<anonymous closure>.<anonymous closure> (package:profile_app/provider/data.dart:54:32)
E/flutter (18902): #1 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:311:23)
E/flutter (18902): #2 ProfileProvider.fetchData.<anonymous closure> (package:profile_app/provider/data.dart:52:13)
E/flutter (18902): #3 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:397:8)
E/flutter (18902): #4 ProfileProvider.fetchData (package:profile_app/provider/data.dart:51:19)
E/flutter (18902): <asynchronous suspension>
E/flutter (18902):
發生錯誤的行在我的代碼中注釋如下:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:core';
class Profile {
final String userName;
final String name;
final String emailId;
final int timePeriod;
final int age;
final String nationality;
final String number;
final int streetNumber;
final String streetName;
final String city;
final String country;
final int postCode;
final String picture;
Profile({
required this.userName,
required this.name,
required this.emailId,
required this.timePeriod,
required this.age,
required this.nationality,
required this.number,
required this.streetNumber,
required this.streetName,
required this.city,
required this.country,
required this.postCode,
required this.picture
});
}
class ProfileProvider with ChangeNotifier {
Map<String, Profile> _data = {};
Map<String, Profile> get data {
return {..._data};
}
Future<void> fetchData() async {
final url = Uri.parse('https://randomuser.me/api/?results=50');
final response = await http.get(url);
final extractedData = json.decode(response.body);
print(extractedData);
Map<String, Profile> map = {};
extractedData.forEach((key, value) => //51:19
map.putIfAbsent(key, () => //52:13
Profile(
userName: value['results'].login.username, //54:32
name: value['results'].name.first,
emailId: value['results'].email,
timePeriod: value['results'].registered.age,
age: value['results'].dob.age,
nationality: value['results'].nat,
number: value['results'].cell,
streetNumber: value['results'].location.street.number,
streetName: value['results'].location.street.name,
city: value['results'].location.city,
country: value['results'].location.country,
postCode: value['results'].location.postcode,
picture: value['results'].picture.large
)
)
);
_data = map;
notifyListeners();
}
}
最初,我認為這是由于我沒有正確定義以下值的資料型別:postCode并且timePeriod它們都在 JSON 回應中定義為整數。但糾正這些也無濟于事。API 呼叫似乎可以正常作業,因為它會毫不猶豫地發送如下回應:
{
"results": [
{
"gender": "male",
"name": {
"title": "Mr",
"first": "André",
"last": "Brunner"
},
"location": {
"street": {
"number": 7771,
"name": "Marktplatz"
},
"city": "Hatzfeld (Eder)",
"state": "Bayern",
"country": "Germany",
"postcode": 39781,
"coordinates": {
"latitude": "-44.0823",
"longitude": "-161.4976"
},
"timezone": {
"offset": " 8:00",
"description": "Beijing, Perth, Singapore, Hong Kong"
}
},
"email": "[email protected]",
"login": {
"uuid": "01dca515-c167-4eeb-a217-60e5178010c8",
"username": "bigladybug476",
"password": "buck",
"salt": "WhBB53R6",
"md5": "f0594b35b2b2baf0c434546e64f0fa05",
"sha1": "db3586cac4b75d2d0c31ad5b6af6061b07aa1b60",
"sha256": "a7225266f739056b352ce001bd76746c60f6e1f0c9955fc983bee3c9f949d8e9"
},
"dob": {
"date": "1946-11-28T06:55:28.967Z",
"age": 75
},
"registered": {
"date": "2018-05-26T04:04:45.356Z",
"age": 3
},
"phone": "0145-0007517",
"cell": "0170-7712395",
"id": {
"name": "",
"value": null
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/31.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/31.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/31.jpg"
},
"nat": "DE"
}
}
uj5u.com熱心網友回復:
有點難以解釋是什么問題,因為代碼有點混亂。
第一的; 你有這條線:
final extractedData = json.decode(response.body);
所以讓我們記住,extractedData 是一個Map<String, dynamic>包含 json 回應的。
那么:
extractedData.forEach((key, value) => ...
這是有趣的部分,對于 JSON 回應中的每個鍵,您正在運行一些帶有鍵和值的代碼。但這里是令人困惑的地方,因為您發布的回應肯定是錯誤的,它不是有效的 JSON,所以我無法確切地告訴您此代碼將如何運行,但我可以告訴您一件事:
代碼第一次運行時,鍵將等于“結果”,值將是一個包含一堆物件的串列
這是因為 'results' 是 JSON 回應中的第一個鍵。
所以當你這樣做時:
userName: value['results'].login.username,
value 是一個串列,但您試圖訪問一個鍵,就好像它是一個地圖一樣,因此您會收到錯誤訊息。
我不確定解決方案是什么,因為我不知道您希望此代碼做什么。
您的代碼中還有另一個錯誤
您無法通過點運算子訪問地圖的值,您需要使用[],因此即使您正確閱讀value['results']呼叫.login也會拋出錯誤
所以value['results'].login.username應該是value['results']['login']['username']
uj5u.com熱心網友回復:
我建議您使用該包json_serializable來幫助您創建從 JSON 轉換和為您的模型類轉換為 JSON 的方法。
在您的情況下,您將擁有以下方法:
factory Profile.fromJson(Map<String, dynamic> json) => Profile(
username: json['username'] as String? ?? '',
name: json['name'] as String? ?? '',
emailId: json['emailId'] as String? ?? '',
...
);
然后在你的fetchData()方法中你可以這樣做:
final jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
final profile = Profile.fromJson(jsonMap);
您也可以使用此鏈接: JSON to Dart Converter 幫助您從 JSON 回應字串生成 Dart 類。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/344843.html
標籤:扑
