【问题标题】:Display JSON data in Flutter在 Flutter 中显示 JSON 数据
【发布时间】:2021-11-27 04:38:17
【问题描述】:

我想显示一些我从 API 接收到的数据,这是我从 Node JS 服务器接收到的数据:

[
    {
        "NAME": "Matematicas"
    },
    {
        "NAME": "Naturales"
    },
    {
        "NAME": "Ciencias Sociales"
    },
    {
        "NAME": "Lenguaje"
    },
    {
        "NAME": "Religion"
    }
]

这就是我在前端接收数据的方式(由@Mofidul Islam 更新):

Future<List<Subject>> fetchSubject() async {
  var url = Uri.http('localhost:8000', "/subjects");
  var prefs = await SharedPreferences.getInstance();
  var token = prefs.getString('token');
  final response = await http.get(
      Uri.parse('http://localhost:8000/subjects'),
      headers: {'x-access-token': token!});

  print(response.body);
  List<dynamic> list = "[" + response.body + "]" as List<dynamic>;
  List<Subject> subjectList = [];

  list.forEach((element) {
    subjectList.add(Subject.fromJson(element));
  });

  return subjectList;
}

这是处理传入数据的类(已更新 @Mofidul Islam):

class Subject {
  final String name;

  Subject({
    required this.name,
  });

  factory Subject.fromJson(Map<String, dynamic> json) {
    return Subject(name: json['NAME'] as String);
  }

  parseJson(String responseBody) {
    final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
    return parsed.map<Subject>((json) => Subject.fromJson(json)).toList();
  }
}

这是我的初始化状态:

void initState() {
    super.initState();    
    futureSubject = fetchSubject();
  }

这就是我尝试显示数据的方式:

Widget build(BuildContext context) {
return MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Materias',
  theme: ThemeData(
    primarySwatch: Colors.green,
  ),
  home: Scaffold(
    appBar: AppBar(
      title: const Text('Materias'),
    ),
    body: Center(
      child: FutureBuilder<List<Subject>>(
        future: futureSubject,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Column(
              children: snapshot.data!
                  .map((subject) => Text(subject.name))
                  .toList(),
            );
          } else if (snapshot.hasError) {
            return Text('${snapshot.error}');
          }
          return const CircularProgressIndicator();
        },
  

),
    ),
  ),
);

}

但是,页面加载时唯一显示的是:

Matematicas

我正在努力实现两件事:

  1. 以列表方式显示数据,例如:
Subject Name 
Matematicas 
Naturales 
Ciencias Sociales 
Lenguaje Religion
  1. 能够在点击时将它们用作另一个页面的链接

PD:如果我在return Subject.fromJson(jsonDecode(response.body)[0]); 上删除索引访问[0] 我得到Expected a value of type Map&lt;String, dynamic&gt; but got one of type List&lt;dynamic&gt;

关于如何完成此操作的任何建议或指南?

感谢您的宝贵时间

【问题讨论】:

    标签: node.js json flutter dart


    【解决方案1】:

    你需要循环播放它

    parseJson(String responseBody) {
        final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
        return parsed
            .map<Subject>((json) => Subject.fromJson(json))
            .toList();
      }
    

    并将您的 api 调用更改为此

    Future<List<Subject>> fetchSubject() async {
      .....
      return parseJson(json.encode(response.body));
    }
    

    对不起我的英语。

    【讨论】:

    • 我试过这个,但我在哪里打电话parseJson()?如果我尝试在 Future&lt;List&lt;Subject&gt;&gt; 方法中调用它,则表示该函数未定义。很抱歉花了这么长时间来回答,非常感谢您的帮助
    【解决方案2】:

    请试试这个并从api方法返回列表

    Future<List<Subject>> fetchSubject() async {
      var url = Uri.http('localhost:8000', "/subjects");
      var prefs = await SharedPreferences.getInstance();
      var token = prefs.getString('token');
      final response = await http.get(Uri.parse('http://localhost:8000/subjects'),
          headers: {'x-access-token': token!});
    List<dynamic>list=response.body as List<dynamic>;
          List<Subject>subjectList=[];
            
          list.forEach((element){
            subjectList.add(Subject.fromJson(element));
          });
    
          return subjectList;
      
    }
    

    像这样重构 UI

    Center(
              child: FutureBuilder<List<Subject>>(
                future: futureSubject,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return Column(children: snapshot.data.map((subject)=>Text(subject.name)).toList(),);
                  } else if (snapshot.hasError) {
                    return Text('${snapshot.error}');
                  }
                  return const CircularProgressIndicator();
                },
              ),
            )
    

    【讨论】:

    • 我从 api 方法 Future&lt;Subject&gt;fetchSubject() 中尝试了这个,我以这种方式返回它 return subjectList[0],当我运行应用程序时,我得到 Expected value ot type List&lt;dynamic&gt; but got one of String。如果我尝试按照您提到的方式返回它,subject[0].name 我会在返回子句中收到此错误:A value of type 'String' can't be returned from the function 'fetchSubject' because it has a return type of 'Future&lt;List&lt;Subject&gt;&gt;'.。也许我错过了什么。
    • 您应该返回 subjectList 而不是 subjectList[0] 并且函数返回类型应该是 Future> 而不是 Future 并重构您的 ui 以接收 List
    • 我已经修改了我的答案。请看看它是否有帮助@Irwin
    • 谢谢,尝试了更新的例子,我得到了Expected a value of type List&lt;dynamic&gt; but got one of String。我不得不提到我必须在return Column(children: snapshot.data.map((subject)=&gt;Text(subject.name)).toList(),); 中添加一个! 虽然我知道我做错了什么......
    • 元素不是 String 。它的 Map 像 {"Name":"Mathermaticts"}
    猜你喜欢
    • 2020-02-11
    • 2021-11-13
    • 2019-11-15
    • 2021-08-18
    • 2022-01-13
    • 2021-12-15
    • 2021-06-25
    • 2021-04-27
    • 2018-11-21
    相关资源
    最近更新 更多