json - 在Flutter中显示来自API Json响应的结果时出现错误

标签 json flutter dart

我使用几个示例的组合构建了以下内容,但无法显示结果。这是我第一次尝试在macOS应用中使用flutter / dart,因此可能存在很多错误。我正在http://dummy.restapiexample.com/https://app.quicktype.io/使用API​​演示来生成解析逻辑。

我在应用程序中得到的错误是:type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<Data>'
在应用程序中,我输入名称Joe和32岁。从调试输出中可以看到http.post正常工作:flutter: {status: success, data: {name: Joe, salary: 123, age: 32, id: 95}}
主镖

import 'package:flutter/material.dart';
import 'package:apitestapp/widgets/ApiTest.dart';

var text = TextEditingController();

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
bool pressed = false;
final myController1 = TextEditingController();
final myController2 = TextEditingController();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ApiTest',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('ApiTest'),
        ),
        body:
        Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextField(
            controller: myController1,
            decoration: InputDecoration(
            hintText: 'Enter your name',
            hintStyle: TextStyle(color: Colors.grey)
            ),
           ),
           TextField(
            controller: myController2,
            decoration: InputDecoration(
            hintText: 'Enter your age',
            hintStyle: TextStyle(color: Colors.grey)
            ),
           ),
          RaisedButton(
            child: Text('Get ApiTest Data'),
            onPressed: () {
              nameTest = myController1.text;
              ageTest = myController2.text;
              print("Data sent: Name is $nameTest and age is $ageTest");
              setState(() {
              pressed = true;
              });
            },
          ),
          ApiTest(),
        ],
        ),
      ),
    );
  }
}

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

String nameTest = "";
String ageTest = "";

// From https://app.quicktype.io/
Welcome welcomeFromJson(String str) => Welcome.fromJson(json.decode(str));

String welcomeToJson(Welcome data) => json.encode(data.toJson());

class Welcome {
    String status;
    Data data;

    Welcome({
        this.status,
        this.data,
    });

    factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
        status: json["status"],
        data: Data.fromJson(json["data"]),
    );

    Map<String, dynamic> toJson() => {
        "status": status,
        "data": data.toJson(),
    };
}

class Data {
    String name;
    String salary;
    String age;
    String id;

    Data({
        this.name,
        this.salary,
        this.age,
        this.id,
    });

    factory Data.fromJson(Map<String, dynamic> json) => Data(
        name: json["name"],
        salary: json["salary"],
        age: json["age"],
        id: json["id"],
    );

    Map<String, dynamic> toJson() => {
        "name": name,
        "salary": salary,
        "age": age,
        "id": id,
    };
}

class ApiTest extends StatefulWidget {
  ApiTest({Key key}) : super(key: key);

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

class _ApiTestState extends State<ApiTest> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Data>(
      future: fetchPost(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
        return Row(
          children: [
              Text(snapshot.data.name),
              Text(snapshot.data.age),
          ],
        );
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        }
        return CircularProgressIndicator();
        },
      );
    }
  Future<Data> fetchPost() async {
    var url = "http://dummy.restapiexample.com/api/v1/create";
    var body = json.encode({"name":"$nameTest","salary":"123","age":"$ageTest"});

    Map<String,String> headers = {
      'Content-type' : 'application/json', 
      'Accept': 'application/json',
    };

  final response = await http.post(url, body: body, headers: headers);
  final responseJson = json.decode(response.body);
  print(responseJson);
  return responseJson;
  }
}

App Screenshot

谢谢你的帮助。

最佳答案

您可以在下面复制粘贴运行完整代码

步骤1:修改fetchPost()

 Welcome welcome = welcomeFromJson(response.body);  
 return welcome.data;

步骤2:将idString更改为int
class Data {
  String name;
  String salary;
  String age;
  int id;

工作演示

enter image description here

完整的代码
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

String nameTest = "";
String ageTest = "";

// From https://app.quicktype.io/
Welcome welcomeFromJson(String str) => Welcome.fromJson(json.decode(str));

String welcomeToJson(Welcome data) => json.encode(data.toJson());

class Welcome {
  String status;
  Data data;

  Welcome({
    this.status,
    this.data,
  });

  factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
    status: json["status"],
    data: Data.fromJson(json["data"]),
  );

  Map<String, dynamic> toJson() => {
    "status": status,
    "data": data.toJson(),
  };
}

class Data {
  String name;
  String salary;
  String age;
  int id;

  Data({
    this.name,
    this.salary,
    this.age,
    this.id,
  });

  factory Data.fromJson(Map<String, dynamic> json) => Data(
    name: json["name"],
    salary: json["salary"],
    age: json["age"],
    id: json["id"],
  );

  Map<String, dynamic> toJson() => {
    "name": name,
    "salary": salary,
    "age": age,
    "id": id,
  };
}

class ApiTest extends StatefulWidget {
  ApiTest({Key key}) : super(key: key);

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

class _ApiTestState extends State<ApiTest> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Data>(
      future: fetchPost(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Row(
            children: [
              Text(snapshot.data.name),
              Text(snapshot.data.age),
            ],
          );
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        }
        return CircularProgressIndicator();
      },
    );
  }
  Future<Data> fetchPost() async {
    var url = "http://dummy.restapiexample.com/api/v1/create";
    var body = json.encode({"name":"$nameTest","salary":"123","age":"$ageTest"});

    Map<String,String> headers = {
      'Content-type' : 'application/json',
      'Accept': 'application/json',
    };

    final response = await http.post(url, body: body, headers: headers);
    //final responseJson = json.decode(response.body);
    print(response.body);
    Welcome welcome = welcomeFromJson(response.body);
    //print(responseJson);
    return welcome.data;
  }
}

var text = TextEditingController();

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  bool pressed = false;
  final myController1 = TextEditingController();
  final myController2 = TextEditingController();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ApiTest',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('ApiTest'),
        ),
        body:
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            TextField(
              controller: myController1,
              decoration: InputDecoration(
                  hintText: 'Enter your name',
                  hintStyle: TextStyle(color: Colors.grey)
              ),
            ),
            TextField(
              controller: myController2,
              decoration: InputDecoration(
                  hintText: 'Enter your age',
                  hintStyle: TextStyle(color: Colors.grey)
              ),
            ),
            RaisedButton(
              child: Text('Get ApiTest Data'),
              onPressed: () {
                nameTest = myController1.text;
                ageTest = myController2.text;
                print("Data sent: Name is $nameTest and age is $ageTest");
                setState(() {
                  pressed = true;
                });
              },
            ),
            ApiTest(),
          ],
        ),
      ),
    );
  }
}

关于json - 在Flutter中显示来自API Json响应的结果时出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60030510/

相关文章:

php - 从 json 字符串获取特定值时出现问题

PHP:通过 jQuery ajax 帮助检索 JSON

java - 来自 RESTful 请求的 JSON 解析异常

json - 如何在Flutter中跳过Json映射中的特定键

flutter : Futurebuilder not catch exception

flutter - 替换 blocprovider 中的 Bloc 实例

dart - 使用流进行 PropertyChanges

java - Gson 不构造内部对象

dart - 事件选项卡未使用 BottomNavigationBar 保持突出显示(打开然后关闭)

testing - 如何测试 dart 类静态常量?