【问题标题】:Parse complex JSON In flutter and type 'Future<dynamic>' is not a subtype of type 'Future<AllUsers>'在颤振中解析复杂的 JSON 类型“Future<dynamic>”不是“Future<AllUsers>”类型的子类型
【发布时间】:2019-04-05 15:17:53
【问题描述】:

我只是解析复杂的 JSON 并显示在 listView 上以供学习。

API: https://jsonplaceholder.typicode.com/users

1) 模型类

class AllUsers {
  final List<User> alluser;

  AllUsers({this.alluser});

  factory AllUsers.formJson(List<dynamic> jsonArr){
    List<User> arruser = jsonArr.map((f)=> User.formJson(f)).toList();
    return AllUsers(
      alluser:  arruser
    );
  }
}
class User {
  int id;
  String name;
  String email;
  Address address;
  String phone;
  String website;
  Company company;

  User({this.id, this.name, this.email, this.address, this.phone, this.website, this.company});

  factory User.formJson(Map<String, dynamic> jsonObj) {
    return User(
      id: jsonObj['id'],
      name: jsonObj['name'],
      email: jsonObj['email'],
      address: Address.formJson(jsonObj['address']),
      phone: jsonObj['phone'],
      website: jsonObj['website'],
      company: Company.formJson(jsonObj['company'])
    );
  }
} 
class Address {
  String street;
  String suite;
  String city;
  String zipcode;
  Geo geo;

  Address({this.street, this.suite, this.city, this.zipcode, this.geo});

  factory Address.formJson(Map<String, dynamic> jsonObj) {
    return Address(
      street: jsonObj['street'],
      suite: jsonObj['suite'],
      city: jsonObj['city'],
      zipcode: jsonObj['zipcode'],
      geo: Geo.formJson(jsonObj['geo'])
    );
  }
} 
class Geo {
  String lat;
  String lng;

  Geo({this.lat, this.lng});

  factory Geo.formJson(Map<String, dynamic> jsonObj) {
    return Geo(
      lat: jsonObj['lat'],
      lng: jsonObj['lng'],
    );
  }
} 
class Company {
  String name;
  String catchPhrase;
  String bs;

  Company({this.name, this.catchPhrase, this.bs});

  factory Company.formJson(Map<String, dynamic> jsonObj) {
    return Company(
      name: jsonObj['name'],
      catchPhrase: jsonObj['catchPhrase'],
      bs: jsonObj['bs']
    );
  }
}

2)ViewModel

import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:parsejsonlist/All Screens/Home/Model/users.dart';

class UserViewModel {
  Future<AllUsers> callWebserviceForFetchUserData() async{
    var listOfUser = await http.get('https://jsonplaceholder.typicode.com/users');
    List<User> decodedJSON = json.decode(listOfUser.body);
    AllUsers arrayOfAlluser = AllUsers.formJson(decodedJSON);
    print("arrayOfAlluser $arrayOfAlluser");
    return arrayOfAlluser;
  }
}

3) 查看部分代码。

import 'package:flutter/material.dart';
import 'package:parsejsonlist/All Screens/Home/Model/users.dart';
import 'package:parsejsonlist/All Screens/Home/ModelView/userviewmodel.dart';

class HomeSceen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeSceen> {

  AllUsers arryOfUser;
  UserViewModel userViewmodel;

  @override 
  initState(){
    super.initState();     
    userViewmodel = UserViewModel();
  }

  callMethodFetchUserData() async {
    arryOfUser = await userViewmodel.callWebserviceForFetchUserData();
    User userRes =  arryOfUser.alluser[0];
    print("response === >> ${userRes.company.catchPhrase}");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("JSON Parsing")
      ),
      body: Container(
        child: FutureBuilder<AllUsers>(
          future: callMethodFetchUserData(),
          builder: (context, data){
            return setupListView();
          },          
        ),
      ),
    );
  }

  Widget setupListView(){
  return ListView.builder(
    itemCount: arryOfUser.alluser.length,
    itemBuilder: (BuildContext context, int index) {
      User userdata = arryOfUser.alluser[index];
      setupListTile(userdata);
    },
  );
 }



    Widget setupListTile(User userdata){
  return ListTile(
    leading: CircleAvatar(
      backgroundColor: Colors.orangeAccent,
      child: Text(userdata.name[0].toUpperCase(), 
      style: TextStyle(color: Colors.white)),
    ),
    title: Text(userdata.name),
    subtitle: Text(userdata.company.name),    
  );
 }
}

所以,我的问题是每次我都因为很多错误而失败。

类型“未来”不是类型“未来”的子类型

我知道有很多错误,但我是 Flutter 的新手。 我哪里错了?如何解决这个问题,请指导我正确的方向。

更新

child: FutureBuilder<List<User>>(
          future: userViewmodel.callWebserviceForFetchUserData(),
          builder: (BuildContext context, AsyncSnapshot<List<User>> snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return Text('Press button to start.');
              case ConnectionState.active:
              case ConnectionState.waiting:
                return Text('Awaiting result...');
              case ConnectionState.done:
                if (snapshot.hasError) return Text('Error: ${snapshot.error}');
                return setupListView(snapshot.data);
            }
            return null;
          },

Getting Error: "Type List<dynamic> is not a subtype of type List<User>"

模型类有错误吗?

【问题讨论】:

  • 这些行看起来很可疑:List&lt;User&gt; decodedJSON = json.decode(listOfUser.body); AllUsers arrayOfAlluser = AllUsers.formJson(decodedJSON); 你确定这些表达式的类型是正确的吗?我会同时使用var
  • 其实我也不是很清楚。我根据我的理解编写了代码,所以使用了你所说的 var 但同样的问题发生了。

标签: dart flutter


【解决方案1】:

丢弃AllUsers 类型和arryOfUser 成员。你不需要它们,而且把它们放进去,你就没有达到 FutureBuilder 的期望。

class UserViewModel {
  Future<List<User>> fetchUserData() async {
    var response = await http.get('https://jsonplaceholder.typicode.com/users');
    List<User> users = json.decode(response.body).map((u) => User.formJson(u)).toList();
    print("users $users");
    print("response === >> ${users[0].company.catchPhrase}");
    return users;
  }
}

class HomeScreenState extends State<HomeSceen> {

  UserViewModel userViewmodel;

  @override 
  initState(){
    super.initState();     
    userViewmodel = UserViewModel();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("JSON Parsing")
      ),
      body: Container(
        child: FutureBuilder<List<User>>(
          future: userViewmodel.fetchUserData(), 
          builder: (context, snap){
            return setupListView(snap.data);
          },          
        ),
      ),
    );
  }

  Widget setupListView(List<User> users){
  return ListView.builder(
    itemCount: users.length,
    itemBuilder: (BuildContext context, int index) {
      setupListTile(users[index]);
    },
  );
 }

 Widget setupListTile(User userdata){
  return ListTile(
    leading: CircleAvatar(
      backgroundColor: Colors.orangeAccent,
      child: Text(userdata.name[0].toUpperCase(), 
      style: TextStyle(color: Colors.white)),
    ),
    title: Text(userdata.name),
    subtitle: Text(userdata.company.name),    
  );
 }
}

【讨论】:

  • 'AsyncSnapshot>' 不能在返回 setupListView(data) 时分配给参数类型 'List';在 FutureBuilder 中
  • @Govaadiyo 查看编辑。这是我在猜测 Flutter 并在谷歌上搜索错误中的类型名
  • flutter:在构建 FutureBuilder>(dirty, state: flutter: _FutureBuilderState>#30a18) 时引发了以下 NoSuchMethodError:flutter:调用了 getter 'length'为空。颤振:接收者:空颤振:尝试调用:长度
  • @Govaadiyo 你可能也想看看this
  • 好的,谢谢你的教程,它会增加我的知识。如果需要任何帮助,我会评论你.. 感谢您的支持。
猜你喜欢
  • 2020-01-01
  • 2021-10-18
  • 2021-10-21
  • 1970-01-01
  • 2020-09-24
  • 2020-09-11
  • 2020-10-13
  • 2021-02-10
  • 1970-01-01
相关资源
最近更新 更多