skip to Main Content

I am making a little bit of progress in understanding how to parse JSON. I have added an example of the JSON I get back from the API below. Does this JSON represent a List[Map<String, dynamic>] ?

This is the error I am getting when I run the code:

enter image description here

I did not write the code for GetPropertyDataFromApi. It came from a website that converts JSON schema to Dart. I am going through a flutter course in Udemy.com but I have not come across anything to help me with this error.

I have received a couple of answers for this in a separate thread here but I am too new to Dart and JSON to really know how to implement the suggestions. I am creating this new question because I had more to write than what a comment would allow in the original thread.

import 'dart:convert';

GetPropertyDataFromApi getDataFromApiFromJson(String str) => GetPropertyDataFromApi.fromJson(json.decode(str)); // ERROR IS HERE

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;
    }
}

This is the sample JSON data I get back from the API:

"[{"addressLine1":"5500 Grand Lake Dr","city":"San
Antonio","state":"TX","zipCode":"78244","formattedAddress":"5500 Grand
Lake Dr, San Antonio, TX
78244","assessorID":"05076-103-0500","bedrooms":3,"county":"Bexar","legalDescription":"CB
5076A BLK 3 LOT 50","squareFootage":1878,"subdivision":"CONV A/S
CODE","yearBuilt":1973,"bathrooms":2,"lotSize":8850,"propertyType":"Single
Family","lastSaleDate":"2004-06-16T17:00:00.000Z","features":{"architectureType":"Contemporary","cooling":true,"coolingType":"Central","exteriorType":"Wood
Siding","floorCount":1,"foundationType":"Slab / Mat /
Raft","garage":true,"garageType":"Garage","heating":true,"heatingType":"Forced
Air","pool":true,"roofType":"Asphalt
Shingle","roomCount":5,"unitCount":1},"taxAssessment":{"2017":{"value":134880,"land":18760,"improvements":116120},"2018":{"value":126510,"land":18760,"improvements":107750},"2019":{"value":135430,"land":23450,"improvements":111980},"2020":{"value":142610,"land":23450,"improvements":119160},"2021":{"value":163440,"land":45050,"improvements":118390},"2022":{"value":197600,"land":49560,"improvements":148040}},"propertyTaxes":{"2017":{"total":3064},"2018":{"total":2890},"2019":{"total":2984},"2020":{"total":3023},"2021":{"total":3455},"2022":{"total":4091}},"owner":{"names":["MICHAEL
SMITH"],"mailingAddress":{"id":"149-Weaver-Blvd,—264,-Weaverville,-NC-28787","addressLine1":"149
Weaver
Blvd","city":"Weaverville","state":"NC","zipCode":"28787","addressLine2":"#
264"}},"id":"5500-Grand-Lake-Dr,-San-Antonio,-TX-78244","longitude":-98.351451,"latitude":29.475953}]"

Please be patient with me while I am trying to learn.

2

Answers


  1. Chosen as BEST ANSWER

    This is the code where I call getDataFromApiFromJson()

    import 'package:clientminer/models/get_property_data.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    
    class RemoteServicePropertyData {
      Future<List<Items>?> getItems() async {
        var client = http.Client();
        var parameters;
    
        parameters = '?address=6303%20newcastle%20drive%2C%20bellaire%2C%20Texas';
    
        // var uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
        var url = Uri.parse(
            "https://realty-mole-property-api.p.rapidapi.com/properties?address=5500%20Grand%20Lake%20Dr%2C%20San%20Antonio%2C%20TX%2C%2078244");
        //'https://realty-mole-property-api.p.rapidapi.com/properties');// + parameters);
        var response = await client.get(
          url,
          headers: {
            'X-RapidAPI-Key': '51ced1b32emsh509f82e1d58ae16p1ad6e6jsn75d75166a8b4',
            'X-RapidAPI-Host': 'realty-mole-property-api.p.rapidapi.com'
          },
        );
        if (response.statusCode == 200) {
          var jsonData = response.body; // This contains the json returned from the API
    
          // return itemsFromJson(json);
          getDataFromApiFromJson(
              jsonData); // Call the class in get_property_data.dart to parse the json
        } else {
          print('Status Code: ' + response.statusCode.toString());
        }
      }
    }
    

  2. at getItems() function , change
    var jsonData = response.body; // This contains the json returned from the API
    
          // return itemsFromJson(json);
          getDataFromApiFromJson(
              jsonData); // Call the class in get_property_data.dart to parse the json
    to
    
     final jsonData = response.body[0]; 
          getDataFromApiFromJson(
              jsonData); 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search