我该如何连接到该API

时间:2019-09-10 10:51:41

标签: flutter dart

我有这个api:https://cmfiflutterapp.s3-ap-southeast-2.amazonaws.com/latest.json

我正试图从中获取实时数据。我的问题是我的映射在这里是错误的:

DestinationFolder="$(OutPutPath)\Testresults"

如果数组是这样,则上面的映射将起作用:

    return new User(
        Ctry: json['Ctry'],
        PeopNameInCountry: json['PeopNameInCountry'],
        Population: json['Population'],
        PrimaryLanguageName: json['PrimaryLanguageName'],
}

该数组在数组之前有一个“元”和一个“数据”块。

[object 1},object 2},{object 3}...etc]

我尝试添加 "meta": { "pagination": { "total_count": 17097, "total_pages": 171, "current_page": 1, "limit": 100 } }, "data": [ {object 1}, {object 2}, {object 3} ], "status": { "message": "Success!", "status_code": 200 } } ,但没有成功。我该如何调整使其正常工作?:

['data']

非常感谢您的帮助...谢谢大家!

2 个答案:

答案 0 :(得分:1)

在您发布的json数据中,data键的值为List<dynamic>类型,而不是Map。因此,json['data']总是会引发错误。

相反,您可以尝试执行以下操作-(此代码是示例,而不是确切的实现)

List<User> users = (json['data') as List<dynamic>).map((jsonObj) {
  return User.formJson(jsonObj);
}).toList();

上面的代码将在User.fromJson列表中的每个对象上调用json['data']工厂方法。

希望有帮助!

答案 1 :(得分:0)

我对您的代码进行了一些更改,请检查它是否对您有用

import 'dart:async';
import 'dart:core';

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

class Api extends StatefulWidget {
  @override
  ApiScreenState createState() => ApiScreenState();
}

class ApiScreenState extends State<Api> {
  List<User> _list = [];
  List<User> _search = [];
  var loading = false;

  Future<Null> fetchData() async {
    setState(() {
  loading = true;
    });
    _list.clear();
    final response = await http.get(
    "https://cmfiflutterapp.s3-ap-southeast-2.amazonaws.com/latest.json");
if (response.statusCode == 200) {
  ResponseModel model = responseModelFromJson(response.body);
  setState(() {
    _list.addAll(model.data);
    loading = false;
  });
    }
  }

  TextEditingController controller = new TextEditingController();

  onSearch(String text) async {
_search.clear();
if (text.isEmpty) {
  setState(() {});
  return;
}

_list.forEach((f) {
  if (f.ctry.contains(text) ||
      f.peopNameInCountry.toString().contains(text)) _search.add(f);
});

  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
  appBar: AppBar(),
  body: Container(
    child: Column(
      children: <Widget>[
        Container(
          padding: EdgeInsets.all(10.0),
          color: Colors.blue,
          child: Card(
            child: ListTile(
              leading: Icon(Icons.search),
              title: TextField(
                controller: controller,
                onChanged: onSearch,
                decoration: InputDecoration(
                    hintText: "Search", border: InputBorder.none),
              ),
              trailing: IconButton(
                onPressed: () {
                  controller.clear();
                  onSearch('');
                },
                icon: Icon(Icons.cancel),
              ),
            ),
          ),
        ),
        loading
            ? Center(
                heightFactor: 10.0,
                child: CircularProgressIndicator(),
              )
            : Expanded(
                child: _search.length != 0 || controller.text.isNotEmpty
                    ? ListView.builder(
                        itemCount: _search.length,
                        itemBuilder: (context, i) {
                          final b = _search[i];
                          return GestureDetector(
                            onTap: () {
                              Navigator.push(
                                  context,
                                  new MaterialPageRoute(
                                      builder: (context) =>
                                          DetailPage(_search[i])));
                              debugPrint('TopNav');
                            },
                            child: Container(
                                padding: EdgeInsets.all(10.0),
                                child: Column(
                                  crossAxisAlignment:
                                      CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text(
                                      b.ctry,
                                      style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          fontSize: 18.0),
                                    ),
                                    SizedBox(
                                      height: 4.0,
                                    ),
                                    Text(b.peopNameInCountry),
                                  ],
                                )),
                          );
                        },
                      )
                    : ListView.builder(
                        itemCount: _list.length,
                        itemBuilder: (context, i) {
                          final a = _list[i];
                          return GestureDetector(
                            onTap: () {
                              Navigator.push(
                                  context,
                                  new MaterialPageRoute(
                                      builder: (context) =>
                                          DetailPage(_list[i])));
                              debugPrint('BottomNav');
                            },
                            child: Container(
                                padding: EdgeInsets.all(10.0),
                                child: Column(
                                  crossAxisAlignment:
                                      CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text(
                                      a.ctry,
                                      style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          fontSize: 18.0),
                                    ),
                                    SizedBox(
                                      height: 4.0,
                                    ),
                                    Text(a.peopNameInCountry),
                                  ],
                                )),
                          );
                        },
                      ),
              ),
      ],
    ),
  ),
);
  }
}

class DetailPage extends StatelessWidget {
  final User user;

  DetailPage(this.user);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
  appBar: AppBar(
    title: Text(user.peopNameInCountry),
    backgroundColor: Colors.lightBlue,
    elevation: 0,
  ),
  body: ListView(
    children: <Widget>[
      Container(
        height: 200,
        decoration: BoxDecoration(
            gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment.centerRight,
                stops: [
              0.5,
              0.9
            ],
                colors: [
              Colors.blue,
              Colors.blue,
            ])),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                Image(
                  image: NetworkImage(user.photoAddress, scale: 1.5),
                ),
              ],
            ),
            SizedBox(
              height: 3,
            ),
            Text(
              user.ctry,
              style: TextStyle(fontSize: 22.0, color: Colors.white),
            ),
            Text(
              user.peopNameInCountry,
              style: TextStyle(fontSize: 16.0, color: Colors.white),
            )
          ],
        ),
      ),
      Container(
        height: 70,
        child: Row(
          children: <Widget>[
            Expanded(
              child: Container(
                color: Colors.deepPurpleAccent,
                child: ListTile(
                  title: Text(
                    user.population.toString(),
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                        fontSize: 20.0),
                  ),
                  subtitle: Text(
                    "Population",
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.red,
                child: ListTile(
                  title: Text(
                    user.bibleStatus.toString(),
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                        fontSize: 20.0),
                  ),
                  subtitle: Text(
                    "Bible Status",
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
      SizedBox(
        height: 3,
      ),
      ListTile(
        title: Text(
          "Bible Translation Status",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          '0 = Unspecfied\n1 = Translation needed\n2 = Translation started\n3 = Portions\n4 = New Testament\n5 = Complete Bible',
          style: TextStyle(fontSize: 12.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Country",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.ctry,
          style: TextStyle(fontSize: 15.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          'People Group',
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.peopNameInCountry,
          style: TextStyle(fontSize: 15.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Region Name",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.regionName,
          style: TextStyle(fontSize: 15.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Affinity Bloc",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.affinityBloc,
          style: TextStyle(fontSize: 15.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Primary Language ",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.primaryLanguageName.toString(),
          style: TextStyle(fontSize: 15.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Religion",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.primaryReligion,
          style: TextStyle(fontSize: 15.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Location In Country",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.leastReached,
          style: TextStyle(fontSize: 14.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Longtitude",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.longitude.toString(),
          style: TextStyle(fontSize: 14.0),
        ),
      ),
      ListTile(
        title: Text(
          "Latitude",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
        subtitle: Text(
          user.latitude.toString(),
          style: TextStyle(fontSize: 14.0),
        ),
      ),
      Divider(),
      ListTile(
        title: Text(
          "Literacy ",
          style: TextStyle(color: Colors.deepOrange, fontSize: 12.0),
        ),
      ),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Image(
          image: NetworkImage(user.mapAddress.toString()),
        ),
      )
    ],
  ),
);
  }
}

// To parse this JSON data, do
//
//     final responseModel = responseModelFromJson(jsonString);

import 'dart:convert';

ResponseModel responseModelFromJson(String str) =>
ResponseModel.fromJson(json.decode(str));

String responseModelToJson(ResponseModel data) =>     json.encode(data.toJson());

class ResponseModel {
  Meta meta;
  List<User> data;
  Status status;

  ResponseModel({
    this.meta,
    this.data,
    this.status,
  });

  factory ResponseModel.fromJson(Map<String, dynamic> json) =>     ResponseModel(
    meta: json["meta"] == null ? null : Meta.fromJson(json["meta"]),
    data: json["data"] == null
        ? null
        : List<User>.from(json["data"].map((x) => User.fromJson(x))),
    status: json["status"] == null ? null : Status.fromJson(json["status"]),
  );

  Map<String, dynamic> toJson() => {
    "meta": meta == null ? null : meta.toJson(),
    "data": data == null
        ? null
        : List<dynamic>.from(data.map((x) => x.toJson())),
    "status": status == null ? null : status.toJson(),
  };
}

class User {
  String ctry;
  String peopNameInCountry;
  int population;
  String leastReached;
  String primaryLanguageName;
  int bibleStatus;
  String primaryReligion;
  String continent;
  String regionName;
  String affinityBloc;
  double longitude;
  double latitude;
  String peopleCluster;
  String frontier;
  int workersNeeded;
  String photoAddress;
  String mapAddress;

  User({
this.ctry,
this.peopNameInCountry,
this.population,
this.continent,
this.regionName,
this.affinityBloc,
this.peopleCluster,
this.leastReached,
this.frontier,
this.workersNeeded,
this.primaryLanguageName,
this.bibleStatus,
this.primaryReligion,
this.photoAddress,
this.mapAddress,
this.longitude,
this.latitude,
  });

  factory User.fromJson(Map<String, dynamic> json) => User(
    ctry: json["Ctry"] == null ? null : json["Ctry"],
    peopNameInCountry: json["PeopNameInCountry"] == null
        ? null
        : json["PeopNameInCountry"],
    population: json["Population"] == null ? null : json["Population"],
    continent: json["Continent"] == null ? null : json["Continent"],
    regionName: json["RegionName"] == null ? null : json["RegionName"],
    affinityBloc:
        json["AffinityBloc"] == null ? null : json["AffinityBloc"],
    peopleCluster:
        json["PeopleCluster"] == null ? null : json["PeopleCluster"],
    leastReached:
        json["LeastReached"] == null ? null : json["LeastReached"],
    frontier: json["Frontier"] == null ? null : json["Frontier"],
    workersNeeded:
        json["WorkersNeeded"] == null ? null : json["WorkersNeeded"],
    primaryLanguageName: json["PrimaryLanguageName"] == null
        ? null
        : json["PrimaryLanguageName"],
    bibleStatus: json["BibleStatus"] == null ? null : json["BibleStatus"],
    primaryReligion:
        json["PrimaryReligion"] == null ? null : json["PrimaryReligion"],
    photoAddress:
        json["PhotoAddress"] == null ? null : json["PhotoAddress"],
    mapAddress: json["MapAddress"] == null ? null : json["MapAddress"],
    longitude:
        json["Longitude"] == null ? null : json["Longitude"].toDouble(),
    latitude: json["Latitude"] == null ? null : json["Latitude"].toDouble(),
  );

  Map<String, dynamic> toJson() => {
    "Ctry": ctry == null ? null : ctry,
    "PeopNameInCountry":
        peopNameInCountry == null ? null : peopNameInCountry,
    "Population": population == null ? null : population,
    "Continent": continent == null ? null : continent,
    "RegionName": regionName == null ? null : regionName,
    "AffinityBloc": affinityBloc == null ? null : affinityBloc,
    "PeopleCluster": peopleCluster == null ? null : peopleCluster,
    "LeastReached": leastReached == null ? null : leastReached,
    "Frontier": frontier == null ? null : frontier,
    "WorkersNeeded": workersNeeded == null ? null : workersNeeded,
    "PrimaryLanguageName":
        primaryLanguageName == null ? null : primaryLanguageName,
    "BibleStatus": bibleStatus == null ? null : bibleStatus,
    "PrimaryReligion": primaryReligion == null ? null : primaryReligion,
    "PhotoAddress": photoAddress == null ? null : photoAddress,
    "MapAddress": mapAddress == null ? null : mapAddress,
    "Longitude": longitude == null ? null : longitude,
    "Latitude": latitude == null ? null : latitude,
  };
}

class Meta {
  Pagination pagination;

  Meta({
    this.pagination,
  });

  factory Meta.fromJson(Map<String, dynamic> json) => Meta(
    pagination: json["pagination"] == null
        ? null
        : Pagination.fromJson(json["pagination"]),
  );

  Map<String, dynamic> toJson() => {
    "pagination": pagination == null ? null : pagination.toJson(),
  };
}

class Pagination {
  int totalCount;
  int totalPages;
  int currentPage;
  int limit;

  Pagination({
    this.totalCount,
    this.totalPages,
    this.currentPage,
    this.limit,
  });

  factory Pagination.fromJson(Map<String, dynamic> json) => Pagination(
    totalCount: json["total_count"] == null ? null : json["total_count"],
    totalPages: json["total_pages"] == null ? null : json["total_pages"],
    currentPage: json["current_page"] == null ? null : json["current_page"],
    limit: json["limit"] == null ? null : json["limit"],
  );

  Map<String, dynamic> toJson() => {
    "total_count": totalCount == null ? null : totalCount,
    "total_pages": totalPages == null ? null : totalPages,
    "current_page": currentPage == null ? null : currentPage,
    "limit": limit == null ? null : limit,
  };
}

class Status {
  String message;
  int statusCode;

  Status({
    this.message,
    this.statusCode,
  });

  factory Status.fromJson(Map<String, dynamic> json) => Status(
    message: json["message"] == null ? null : json["message"],
    statusCode: json["status_code"] == null ? null : json["status_code"],
      );

  Map<String, dynamic> toJson() => {
    "message": message == null ? null : message,
    "status_code": statusCode == null ? null : statusCode,
  };
}