JSON解析函数的正确使用

huangapple go评论90阅读模式
英文:

Correct use of JSON parsing function

问题

Here's the translation of your provided text:

我正在学习如何处理JSON。这是我第一次尝试这样做。

我使用以下代码从API调用中获取JSON数据:

if (response.statusCode == 200) {
      var json = response.body;
      
      // return itemsFromJson(json);
      getDataFromApiFromJson(json);
    }

以下是getDataFromApiFromJson()函数的代码。这段代码是由QuickType.com的JSON转Dart工具生成的:

import 'dart:convert';

GetPropertyDataFromApi getDataFromApiFromJson(String str) => GetPropertyDataFromApi.fromJson(json.decode(str));

String getDataFromApiToJson(GetPropertyDataFromApi data) => json.encode(data.toJson());

class GetPropertyDataFromApi {
    // ...
    // 以及其他类的定义
    // ...
}

当我运行这段代码时,我得到了以下错误:

JSON解析函数的正确使用

我不确定我是否正确调用了函数。

请问我应该如何正确处理这个问题?

英文:

I am learning to work with JSON. This is my first time doing this.

I get the JSON from an API call with this code:

if (response.statusCode == 200) {
      var json = response.body;
      
      // return itemsFromJson(json);
      getDataFromApiFromJson(json);
    }

Here is the code for getDataFromApiFromJson(). This code was generated by QuickType.com JSON to Dart:

import 'dart:convert';
GetPropertyDataFromApi getDataFromApiFromJson(String str) => GetPropertyDataFromApi.fromJson(json.decode(str));
String getDataFromApiToJson(GetPropertyDataFromApi data) => json.encode(data.toJson());
class GetPropertyDataFromApi {
String type;
Items items;
GetPropertyDataFromApi({
required this.type,
required this.items,
});
factory GetPropertyDataFromApi.fromJson(Map<String, dynamic> json) => GetPropertyDataFromApi(
type: json["type"],
items: Items.fromJson(json["items"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"items": items.toJson(),
};
}
class Items {
String type;
ItemsProperties properties;
Items({
required this.type,
required this.properties,
});
factory Items.fromJson(Map<String, dynamic> json) => Items(
type: json["type"],
properties: ItemsProperties.fromJson(json["properties"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": properties.toJson(),
};
}
class ItemsProperties {
AddressLine1 addressLine1;
AddressLine1 city;
AddressLine1 state;
AddressLine1 zipCode;
AddressLine1 formattedAddress;
AddressLine1 assessorId;
AddressLine1 bedrooms;
AddressLine1 county;
AddressLine1 legalDescription;
AddressLine1 squareFootage;
AddressLine1 subdivision;
AddressLine1 yearBuilt;
AddressLine1 bathrooms;
AddressLine1 lotSize;
AddressLine1 propertyType;
AddressLine1 lastSaleDate;
Features features;
TaxAssessment taxAssessment;
PropertyTaxes propertyTaxes;
Owner owner;
AddressLine1 id;
AddressLine1 longitude;
AddressLine1 latitude;
ItemsProperties({
required this.addressLine1,
required this.city,
required this.state,
required this.zipCode,
required this.formattedAddress,
required this.assessorId,
required this.bedrooms,
required this.county,
required this.legalDescription,
required this.squareFootage,
required this.subdivision,
required this.yearBuilt,
required this.bathrooms,
required this.lotSize,
required this.propertyType,
required this.lastSaleDate,
required this.features,
required this.taxAssessment,
required this.propertyTaxes,
required this.owner,
required this.id,
required this.longitude,
required this.latitude,
});
factory ItemsProperties.fromJson(Map<String, dynamic> json) => ItemsProperties(
addressLine1: AddressLine1.fromJson(json["addressLine1"]),
city: AddressLine1.fromJson(json["city"]),
state: AddressLine1.fromJson(json["state"]),
zipCode: AddressLine1.fromJson(json["zipCode"]),
formattedAddress: AddressLine1.fromJson(json["formattedAddress"]),
assessorId: AddressLine1.fromJson(json["assessorID"]),
bedrooms: AddressLine1.fromJson(json["bedrooms"]),
county: AddressLine1.fromJson(json["county"]),
legalDescription: AddressLine1.fromJson(json["legalDescription"]),
squareFootage: AddressLine1.fromJson(json["squareFootage"]),
subdivision: AddressLine1.fromJson(json["subdivision"]),
yearBuilt: AddressLine1.fromJson(json["yearBuilt"]),
bathrooms: AddressLine1.fromJson(json["bathrooms"]),
lotSize: AddressLine1.fromJson(json["lotSize"]),
propertyType: AddressLine1.fromJson(json["propertyType"]),
lastSaleDate: AddressLine1.fromJson(json["lastSaleDate"]),
features: Features.fromJson(json["features"]),
taxAssessment: TaxAssessment.fromJson(json["taxAssessment"]),
propertyTaxes: PropertyTaxes.fromJson(json["propertyTaxes"]),
owner: Owner.fromJson(json["owner"]),
id: AddressLine1.fromJson(json["id"]),
longitude: AddressLine1.fromJson(json["longitude"]),
latitude: AddressLine1.fromJson(json["latitude"]),
);
Map<String, dynamic> toJson() => {
"addressLine1": addressLine1.toJson(),
"city": city.toJson(),
"state": state.toJson(),
"zipCode": zipCode.toJson(),
"formattedAddress": formattedAddress.toJson(),
"assessorID": assessorId.toJson(),
"bedrooms": bedrooms.toJson(),
"county": county.toJson(),
"legalDescription": legalDescription.toJson(),
"squareFootage": squareFootage.toJson(),
"subdivision": subdivision.toJson(),
"yearBuilt": yearBuilt.toJson(),
"bathrooms": bathrooms.toJson(),
"lotSize": lotSize.toJson(),
"propertyType": propertyType.toJson(),
"lastSaleDate": lastSaleDate.toJson(),
"features": features.toJson(),
"taxAssessment": taxAssessment.toJson(),
"propertyTaxes": propertyTaxes.toJson(),
"owner": owner.toJson(),
"id": id.toJson(),
"longitude": longitude.toJson(),
"latitude": latitude.toJson(),
};
}
class AddressLine1 {
Type type;
AddressLine1({
required this.type,
});
factory AddressLine1.fromJson(Map<String, dynamic> json) => AddressLine1(
type: typeValues.map[json["type"]]!,
);
Map<String, dynamic> toJson() => {
"type": typeValues.reverse[type],
};
}
enum Type {
BOOLEAN,
INTEGER,
NUMBER,
STRING
}
final typeValues = EnumValues({
"boolean": Type.BOOLEAN,
"integer": Type.INTEGER,
"number": Type.NUMBER,
"string": Type.STRING
});
class Features {
String type;
Map<String, AddressLine1> properties;
Features({
required this.type,
required this.properties,
});
factory Features.fromJson(Map<String, dynamic> json) => Features(
type: json["type"],
properties: Map.from(json["properties"]).map((k, v) => MapEntry<String, AddressLine1>(k, AddressLine1.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": Map.from(properties).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class Owner {
String type;
OwnerProperties properties;
Owner({
required this.type,
required this.properties,
});
factory Owner.fromJson(Map<String, dynamic> json) => Owner(
type: json["type"],
properties: OwnerProperties.fromJson(json["properties"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": properties.toJson(),
};
}
class OwnerProperties {
Names names;
MailingAddress mailingAddress;
OwnerProperties({
required this.names,
required this.mailingAddress,
});
factory OwnerProperties.fromJson(Map<String, dynamic> json) => OwnerProperties(
names: Names.fromJson(json["names"]),
mailingAddress: MailingAddress.fromJson(json["mailingAddress"]),
);
Map<String, dynamic> toJson() => {
"names": names.toJson(),
"mailingAddress": mailingAddress.toJson(),
};
}
class MailingAddress {
String type;
MailingAddressProperties properties;
MailingAddress({
required this.type,
required this.properties,
});
factory MailingAddress.fromJson(Map<String, dynamic> json) => MailingAddress(
type: json["type"],
properties: MailingAddressProperties.fromJson(json["properties"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": properties.toJson(),
};
}
class MailingAddressProperties {
AddressLine1 id;
AddressLine1 addressLine1;
AddressLine1 city;
AddressLine1 state;
AddressLine1 zipCode;
MailingAddressProperties({
required this.id,
required this.addressLine1,
required this.city,
required this.state,
required this.zipCode,
});
factory MailingAddressProperties.fromJson(Map<String, dynamic> json) => MailingAddressProperties(
id: AddressLine1.fromJson(json["id"]),
addressLine1: AddressLine1.fromJson(json["addressLine1"]),
city: AddressLine1.fromJson(json["city"]),
state: AddressLine1.fromJson(json["state"]),
zipCode: AddressLine1.fromJson(json["zipCode"]),
);
Map<String, dynamic> toJson() => {
"id": id.toJson(),
"addressLine1": addressLine1.toJson(),
"city": city.toJson(),
"state": state.toJson(),
"zipCode": zipCode.toJson(),
};
}
class Names {
String type;
AddressLine1 items;
Names({
required this.type,
required this.items,
});
factory Names.fromJson(Map<String, dynamic> json) => Names(
type: json["type"],
items: AddressLine1.fromJson(json["items"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"items": items.toJson(),
};
}
class PropertyTaxes {
String type;
Map<String, PropertyTaxesProperty> properties;
PropertyTaxes({
required this.type,
required this.properties,
});
factory PropertyTaxes.fromJson(Map<String, dynamic> json) => PropertyTaxes(
type: json["type"],
properties: Map.from(json["properties"]).map((k, v) => MapEntry<String, PropertyTaxesProperty>(k, PropertyTaxesProperty.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": Map.from(properties).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class PropertyTaxesProperty {
String type;
PurpleProperties properties;
PropertyTaxesProperty({
required this.type,
required this.properties,
});
factory PropertyTaxesProperty.fromJson(Map<String, dynamic> json) => PropertyTaxesProperty(
type: json["type"],
properties: PurpleProperties.fromJson(json["properties"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": properties.toJson(),
};
}
class PurpleProperties {
AddressLine1 total;
PurpleProperties({
required this.total,
});
factory PurpleProperties.fromJson(Map<String, dynamic> json) => PurpleProperties(
total: AddressLine1.fromJson(json["total"]),
);
Map<String, dynamic> toJson() => {
"total": total.toJson(),
};
}
class TaxAssessment {
String type;
Map<String, TaxAssessmentProperty> properties;
TaxAssessment({
required this.type,
required this.properties,
});
factory TaxAssessment.fromJson(Map<String, dynamic> json) => TaxAssessment(
type: json["type"],
properties: Map.from(json["properties"]).map((k, v) => MapEntry<String, TaxAssessmentProperty>(k, TaxAssessmentProperty.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": Map.from(properties).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class TaxAssessmentProperty {
String type;
FluffyProperties properties;
TaxAssessmentProperty({
required this.type,
required this.properties,
});
factory TaxAssessmentProperty.fromJson(Map<String, dynamic> json) => TaxAssessmentProperty(
type: json["type"],
properties: FluffyProperties.fromJson(json["properties"]),
);
Map<String, dynamic> toJson() => {
"type": type,
"properties": properties.toJson(),
};
}
class FluffyProperties {
AddressLine1 value;
AddressLine1 land;
AddressLine1 improvements;
FluffyProperties({
required this.value,
required this.land,
required this.improvements,
});
factory FluffyProperties.fromJson(Map<String, dynamic> json) => FluffyProperties(
value: AddressLine1.fromJson(json["value"]),
land: AddressLine1.fromJson(json["land"]),
improvements: AddressLine1.fromJson(json["improvements"]),
);
Map<String, dynamic> toJson() => {
"value": value.toJson(),
"land": land.toJson(),
"improvements": improvements.toJson(),
};
}
class EnumValues<T> {
Map<String, T> map;
late Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
reverseMap = map.map((k, v) => MapEntry(v, k));
return reverseMap;
}
}

I don't know if I am calling the function correct or not.

This is the error I get when I run the code:

JSON解析函数的正确使用

How do I do this in the correct way?

答案1

得分: 1

Like pmatatias mentioned it looks like somewhere you are attempting to parse a list of elements as if they were a single element.

You probably need to add a method that converts a json list into a list of elements. For example:

static List<MyClassName> fromList(List<dynamic> jsonList) {
    final list = <MyClassName>[];
    for (final elementJson in jsonList) {
        final obj = MyClassName.fromJson(elementJson as Map<String, dynamic>);
        list.add(obj);
    }
    return list;
}

or if you want your function to ignore any elements that can't be parsed, you could use:

static List<MyObjectName> fromList(List<dynamic> jsonList) {
    final list = <MyObjectName>[];
    for (final elementJson in jsonList) {
        try {
            final obj = MyObjectName.fromJson(elementJson as Map<String, dynamic>);
            list.add(obj);
        } catch (e) {
            log('error $e parsing $elementJson');
        }
    }
    return list;
}

Then any place that supports a list of objects, call this method. For example, does the "features" property return a list of Features elements? If so, then you would want to replace the line that currently says:

features: Features.fromJson(json["features"]),

with

features: Features.fromList(json["features"]),
英文:

Like pmatatias mentioned it looks like somewhere you are attempting to parse a list of elements as if they were a single element.

You probably need to add a method that converts a json list into a list of elements. For example:

  static List&lt;MyClassName&gt; fromList(List&lt;dynamic&gt; jsonList) {
final list = &lt;MyClassName&gt;[];
for (final elementJson in jsonList) {
final obj = MyClassName.fromJson(elementJson as Map&lt;String, dynamic&gt;);
list.add(obj);
}
return list;
}

or if you want your function to ignore any elements that can't be parsed, you could use:

  static List&lt;MyObjectName&gt; fromList(List&lt;dynamic&gt; jsonList) {
final list = &lt;MyObjectName&gt;[];
for (final elementJson in jsonList) {
try {
final obj = MyObjectName.fromJson(elementJson as Map&lt;String, dynamic&gt;);
list.add(obj);
} catch (e) {
log(&#39;error $e parsing $elementJson&#39;);
}
}
return list;
}

Then any place that supports a list of objects, call this method. For example, does the "features" property return a list of Features elements? If so, then you would want to replace the line that currently says:

 features: Features.fromJson(json[&quot;features&quot;]),

with

 features: Features.fromList(json[&quot;features&quot;]),

答案2

得分: 0

由于我不知道您的JSON格式是什么样的,我将提供一个将JSON序列化为Dart对象的示例。

  • 示例 1

如果您的数据不是一个List,您可以直接进行转换

final jsonData = {
   "type" : "这是示例类型",
   "item" : {} // 另一个嵌套的JSON
 }

// 不要忘记解码 
final GetPropertyDataFromApi objData =
    GetPropertyDataFromApi.fromJson(jsonDecode(jsonData));
  • 示例 2

您的API响应是一个List,即使只有一个项目

final jsonData = [
 {
   "type" : "这是示例类型",
   "item" : {} // 另一个嵌套的JSON
 }
];

// 使用循环处理
final List<GetPropertyDataFromApi> listData = (jsonDecode(jsonData) as List)
    .map((e) => GetPropertyDataFromApi.fromJson(e))
    .toList();

请查看您的数据,如果有一个列表,您也需要将其返回为List

英文:

since I dont know how your json format looks like, I will give example to serialize json to dart object

  • example 1

if your data is not a List, you can directly convert it

final jsonData = {
&quot;type&quot; : &quot;this is example type&quot;,
&quot;item&quot; : {} // another nested json
}
// don&#39;t forget to decode 
final GetPropertyDataFromApi objData =
GetPropertyDataFromApi.fromJson(jsonDecode(jsonData));
  • example 2

you API response are a List, even its only 1 items

final jsonData = [
{
&quot;type&quot; : &quot;this is example type&quot;,
&quot;item&quot; : {} // another nested json
}
];
// handle with looping
final List&lt;GetPropertyDataFromApi&gt; listData = (jsonDecode(jsonData) as List)
.map((e) =&gt; GetPropertyDataFromApi.fromJson(e))
.toList();

> please take a look to your data, if you have a list, you need to
> returned as List too

huangapple
  • 本文由 发表于 2023年8月5日 02:07:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838265.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定