简体   繁体   中英

Parsing JSON in flutter/dart

Hello IM trying to parse this type of json:


{
    "records": [
        {
            "id": "recHSxuQBgXAkT9HR",
            "fields": {
                "Entry ID": "00663",
                "Date ID": "12-12",
                "(Gregorian) Year": " ?",
                "(Coptic) Month": "12-Mesori",
                "(Coptic) Day": "14",
                "Event Category": [
                    "Commemoration"
                ],
                "Event Heading": "Heading01",
                "Name 01 - Title": "Mr.",
                "Name 01 - Name in English": "Jhon",            
                "Name 01 - Suffix": "23rd Pa",
                "DayText": "On this day,..",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "08 - Patriarch of Alexandria"
                ],
                "Number of Saints Mentioned": 1,
                "Regnal Number": "I",
                "Apostolic Throne": "385-412",
                "Entry Title": "Commemoration of "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        },
        {
            "id": "rec3gTgUKo5Co9Qi3",
            "fields": {
                "Entry ID": "00450",
                "Date ID": "08-Paremoude - D30 - 0450",
                "Century": "1st Century",
                "(Gregorian) Year": "68",
                "(Coptic) Month": "08-Paremoud",
                "(Coptic) Day": "30",
                "Event Category": [
                    "Martyrdom"
                ],
                "Event Heading": "Martyrdom of ",
                "Name 01 - Title": "Saint",
                "Name 01 - Name in English": "Mark",
                "Name 01 - Pronoun": "the",
                "Name 01 - Suffix": "Evangelis",
                "DayText": "On this day 2",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "06 - Apostles Order",
                    "07 - Martyrs Order",
                    "08 - Patriarch of Alexandri"
                ],
                "Number of Saints Mentioned": 1,
                "Entry Title": "Martyrdo of the Evangelist ()                                 "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        },

This is my method for geting record:

  Future<Record> _getRecords() async {
    var response = await http.get(Uri.encodeFull("url"),
        headers: {
          "Authorization": "**********",
          "Accept": "application/json"
        });

    Record record;
    if(response == 200) {
      var jsonData = json.decode(response.body);
      record = Record.fromJson(jsonData);
    }else{
      print(response.statusCode);
    }


    return record;
  }

I`m not sure how to format Record class, end currently getting 422 error from server, any help would be nice thank you.Do I need separate class for every array? I need latter on to put data in the ListView... also IM not sure did I correctly included API key for authorization? Tnx

You can copy paste run full code below
You can see Record class definition in full code and use FutureBuilder

code snippet

Record recordFromJson(String str) => Record.fromJson(json.decode(str));
... 
if (response.statusCode == 200) {
  return recordFromJson(jsonString);
...
@override
  void initState() {
    _future = _getRecords();

... 
FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<Record> snapshot) {
              switch (snapshot.connectionState) {

working demo

在此处输入图像描述

full code

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

Record recordFromJson(String str) => Record.fromJson(json.decode(str));

String recordToJson(Record data) => json.encode(data.toJson());

class Record {
  List<RecordElement> records;

  Record({
    this.records,
  });

  factory Record.fromJson(Map<String, dynamic> json) => Record(
        records: List<RecordElement>.from(
            json["records"].map((x) => RecordElement.fromJson(x))),
      );

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

class RecordElement {
  String id;
  Fields fields;
  DateTime createdTime;

  RecordElement({
    this.id,
    this.fields,
    this.createdTime,
  });

  factory RecordElement.fromJson(Map<String, dynamic> json) => RecordElement(
        id: json["id"],
        fields: Fields.fromJson(json["fields"]),
        createdTime: DateTime.parse(json["createdTime"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "fields": fields.toJson(),
        "createdTime": createdTime.toIso8601String(),
      };
}

class Fields {
  String entryId;
  String dateId;
  String gregorianYear;
  String copticMonth;
  String copticDay;
  List<String> eventCategory;
  String eventHeading;
  String name01Title;
  String name01NameInEnglish;
  String name01Suffix;
  String dayText;
  String name01Gender;
  List<String> name01Classification;
  int numberOfSaintsMentioned;
  String regnalNumber;
  String apostolicThrone;
  String entryTitle;
  String century;
  String name01Pronoun;

  Fields({
    this.entryId,
    this.dateId,
    this.gregorianYear,
    this.copticMonth,
    this.copticDay,
    this.eventCategory,
    this.eventHeading,
    this.name01Title,
    this.name01NameInEnglish,
    this.name01Suffix,
    this.dayText,
    this.name01Gender,
    this.name01Classification,
    this.numberOfSaintsMentioned,
    this.regnalNumber,
    this.apostolicThrone,
    this.entryTitle,
    this.century,
    this.name01Pronoun,
  });

  factory Fields.fromJson(Map<String, dynamic> json) => Fields(
        entryId: json["Entry ID"],
        dateId: json["Date ID"],
        gregorianYear: json["(Gregorian) Year"],
        copticMonth: json["(Coptic) Month"],
        copticDay: json["(Coptic) Day"],
        eventCategory: List<String>.from(json["Event Category"].map((x) => x)),
        eventHeading: json["Event Heading"],
        name01Title: json["Name 01 - Title"],
        name01NameInEnglish: json["Name 01 - Name in English"],
        name01Suffix: json["Name 01 - Suffix"],
        dayText: json["DayText"],
        name01Gender: json["Name 01 - Gender"],
        name01Classification:
            List<String>.from(json["Name 01 - Classification"].map((x) => x)),
        numberOfSaintsMentioned: json["Number of Saints Mentioned"],
        regnalNumber:
            json["Regnal Number"] == null ? null : json["Regnal Number"],
        apostolicThrone:
            json["Apostolic Throne"] == null ? null : json["Apostolic Throne"],
        entryTitle: json["Entry Title"],
        century: json["Century"] == null ? null : json["Century"],
        name01Pronoun: json["Name 01 - Pronoun"] == null
            ? null
            : json["Name 01 - Pronoun"],
      );

  Map<String, dynamic> toJson() => {
        "Entry ID": entryId,
        "Date ID": dateId,
        "(Gregorian) Year": gregorianYear,
        "(Coptic) Month": copticMonth,
        "(Coptic) Day": copticDay,
        "Event Category": List<dynamic>.from(eventCategory.map((x) => x)),
        "Event Heading": eventHeading,
        "Name 01 - Title": name01Title,
        "Name 01 - Name in English": name01NameInEnglish,
        "Name 01 - Suffix": name01Suffix,
        "DayText": dayText,
        "Name 01 - Gender": name01Gender,
        "Name 01 - Classification":
            List<dynamic>.from(name01Classification.map((x) => x)),
        "Number of Saints Mentioned": numberOfSaintsMentioned,
        "Regnal Number": regnalNumber == null ? null : regnalNumber,
        "Apostolic Throne": apostolicThrone == null ? null : apostolicThrone,
        "Entry Title": entryTitle,
        "Century": century == null ? null : century,
        "Name 01 - Pronoun": name01Pronoun == null ? null : name01Pronoun,
      };
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  Future<Record> _future;

  Future<Record> _getRecords() async {
    /*var response = await http.get(Uri.encodeFull("url"),
        headers: {
          "Authorization": "**********",
          "Accept": "application/json"
        });
*/
    String jsonString = '''
    {
    "records": [
        {
            "id": "recHSxuQBgXAkT9HR",
            "fields": {
                "Entry ID": "00663",
                "Date ID": "12-12",
                "(Gregorian) Year": " ?",
                "(Coptic) Month": "12-Mesori",
                "(Coptic) Day": "14",
                "Event Category": [
                    "Commemoration"
                ],
                "Event Heading": "Heading01",
                "Name 01 - Title": "Mr.",
                "Name 01 - Name in English": "Jhon",            
                "Name 01 - Suffix": "23rd Pa",
                "DayText": "On this day,..",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "08 - Patriarch of Alexandria"
                ],
                "Number of Saints Mentioned": 1,
                "Regnal Number": "I",
                "Apostolic Throne": "385-412",
                "Entry Title": "Commemoration of "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        },
        {
            "id": "rec3gTgUKo5Co9Qi3",
            "fields": {
                "Entry ID": "00450",
                "Date ID": "08-Paremoude - D30 - 0450",
                "Century": "1st Century",
                "(Gregorian) Year": "68",
                "(Coptic) Month": "08-Paremoud",
                "(Coptic) Day": "30",
                "Event Category": [
                    "Martyrdom"
                ],
                "Event Heading": "Martyrdom of ",
                "Name 01 - Title": "Saint",
                "Name 01 - Name in English": "Mark",
                "Name 01 - Pronoun": "the",
                "Name 01 - Suffix": "Evangelis",
                "DayText": "On this day 2",
                "Name 01 - Gender": "Male",
                "Name 01 - Classification": [
                    "06 - Apostles Order",
                    "07 - Martyrs Order",
                    "08 - Patriarch of Alexandri"
                ],
                "Number of Saints Mentioned": 1,
                "Entry Title": "Martyrdo of the Evangelist ()                                 "
            },
            "createdTime": "2020-04-27T05:30:53.000Z"
        }
        ]
}
    ''';

    var response = http.Response(jsonString, 200);

    if (response.statusCode == 200) {
      return recordFromJson(jsonString);
    } else {
      print(response.statusCode);
    }
  }

  @override
  void initState() {
    _future = _getRecords();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: FutureBuilder(
            future: _future,
            builder: (context, AsyncSnapshot<Record> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('none');
                case ConnectionState.waiting:
                  return Center(child: CircularProgressIndicator());
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (snapshot.hasError) {
                    return Text(
                      '${snapshot.error}',
                      style: TextStyle(color: Colors.red),
                    );
                  } else {
                    return ListView.builder(
                        itemCount: snapshot.data.records.length,
                        itemBuilder: (context, index) {
                          return Card(
                              elevation: 6.0,
                              child: Padding(
                                padding: const EdgeInsets.only(
                                    top: 6.0,
                                    bottom: 6.0,
                                    left: 8.0,
                                    right: 8.0),
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text(
                                      snapshot.data.records[index].fields
                                          .eventHeading,
                                    ),
                                    Spacer(),
                                    Text(
                                      snapshot.data.records[index].fields
                                          .name01NameInEnglish,
                                    ),
                                  ],
                                ),
                              ));
                        });
                  }
              }
            }));
  }
}

There should be more on the server-side or request causing the 422 error. You might want to check them.

To answer your question, since the data is a list of Record , the _getRecords function should be more like this.

Future<List<Record>> _getRecords() async {
  var response = await http.get(
    Uri.encodeFull("url"),
    headers: {
      "Authorization": "**********",
      "Accept": "application/json",
    },
  );

  List<Record> records;

  if (response.statusCode == 200) {
    var jsonData = json.decode(response.body) ?? [];
    records = jsonData.map(Record.fromJson).toList();
  } else {
    print(response.statusCode);
  }

  return records;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM