【问题标题】:app doesn't work because of <asynchronous suspension> &/ Unhandled Exception: type 'String' is not a subtype of type 'FutureOr<Map<dynamic, dynamic>>'由于 <asynchronous suspend> &/ Unhandled Exception: type 'String' is not a subtype of type 'FutureOr<Map<dynamic, dynamic>>' 应用程序无法工作
【发布时间】:2021-08-21 08:15:20
【问题描述】:

flutter 新手尝试注册和登录屏幕 ^_^"

  1. 没有代码错误,但注册无法推送到登录屏幕:在 UI 和控制器 dart 文件中标记没有问题,但测试应用程序返回“”和“未处理的异常:键入 'String ' 不是类型 'FutureOr>'"

    的子类型
  2. 注册和登录中输入的无效/不完整详细信息的错误通知文本不会出现。这应该出现在注册/登录按钮之前。

  3. 当我尝试运行打印登录页面时,屏幕上没有任何反应。

DART FILE OF SIGNUP BELOW:

    class SignUp extends StatefulWidget {
      const SignUp ({Key key}) : super(key: key);
      @override
      _SignUpState createState() => _SignUpState();
    }

    class _SignUpState extends State<SignUp> {
      String username;
      String useremail;
      String userpw;
      String errormessage = '';

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Image(
                  image: AssetImage('logo.png'),
                  width: 70.0,
                ),
                SizedBox(
                  height: 10.0,
                ),
                Container(
                  child: Text('Create Account'),
                ),
                SizedBox(
                  height: 15.0,
                ),
                Container(
                  width: 300.0,
                  child: TextField(
                      obscureText: false,
                      onChanged: (value) {
                        username = value;
                      }),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Container(
                  width: 300.0,
                  child: TextField(
                      obscureText: false,
                      onChanged: (value) {
                        useremail = value;
                      }),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Container(
                  width: 300.0,
                  child: TextField(
                      obscureText: true,
                      onChanged: (value) {
                        userpassword = value;
                      }),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Container(
                  child: Text(
                    errormessage,
                    style: TextStyle(color: Colors.red[500]),
                  ),
                ),
                SizedBox(height: 12.0),
                Container(
                  margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                  child: ElevatedButton(
                    onPressed: () {

                      Map json = {
                        "username": username,
                        "useremail": useremail,
                        "userpw": userpw,
                      };
                      //print(json);

                      UserSignUp(json).then((result) {
                        if (result['error'] != null) {
                          setState(() {
                            errormessage = result['error'];
                          });
                        } else {
                          setState(() {
                            errormessage = '';
                          });
                          Navigator.push(context,
                              MaterialPageRoute(builder: (context) => SignInPage()));
                        }
                      });
                    },
                    style: ElevatedButton.styleFrom(
                      primary: Color(0xff04A148C),
                      onPrimary: Colors.blue[900],
                      padding: EdgeInsets.only(
                          left: 70.0, top: 10.0, right: 70.0, bottom: 10.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10.0),
                      ),
                    ),
                    child: Text(
                      'Sign Up',
                      style: TextStyle(
                        color: Colors.white,
                        fontFamily: 'Roboto',
                        fontSize: 15.0,
                        fontWeight: FontWeight.w600,
                        letterSpacing: 1.0,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }




    DART FILE OF CONTROLLER BELOW:

    final appkey ="appkey random numbers";

    Future<Map> UserSignUp(Map json) async {
      json['appkey'] = appkey;
      final response = await http.post(
        Uri.parse('Sign Up URL'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(json),
      );

      print(response.body);
      if (response.statusCode == 200) {
        return jsonDecode(response.body);
      } else if (response.statusCode == 401) {
        Map error = jsonDecode(response.body);
        Map json = {
          "error": error['data'][0]['msg'],
        };

        return json;
      } else {
        throw Exception('Fail');
      }
    }

    Future<Map> UserSignIn(Map json) async {
      json['appkey'] = appkey;
      final response = await http.post(
        Uri.parse('Sign Up URL'),
        headers: <String, String>{
          'Content-Type': 'application/json;charset=UTF-8',
        },
        body: jsonEncode(json),
      );


      if (response.statusCode == 200) {
        return jsonDecode(response.body);
      } else if (response.statusCode == 400) {
        return jsonDecode(response.body);
      } else {
        throw Exception('Fail');
      }
    }
    


CODE IN THE RUN WINDOW WHEN SIGN-UP IS CLICKED WITH EMPTY TEXT FIELDS ARE BELOW:
    
Performing hot restart...
Syncing files to device AOSP on IA Emulator...
Restarted application in 679ms.
I/flutter (29028): null
I/chatty  (29028): uid=10085(com.example.appname) 1.ui identical 1 line
I/flutter (29028): null
I/flutter (29028): {username: null, useremail: null, userpassword: null}
E/flutter (29028): [ERROR:flutter/lib/ui/ui_dart_state.cc(213)] Unhandled Exception: type 'String' is not a subtype of type 'FutureOr<Map<dynamic, dynamic>>'
E/flutter (29028): #0      registerUser (package:appname/controller.dart:22:5)
E/flutter (29028): <asynchronous suspension>
E/flutter (29028):
p and Sign-in screens not showing:
Made a sign-up and login page with error notification text set to appear if there is incomplete or invalid details.
DART FILE OF SIGNUP BELOW:

class SignUp extends StatefulWidget {
  const SignUp ({Key key}) : super(key: key);
  @override
  _SignUpState createState() => _SignUpState();
}

class _SignUpState extends State<SignUp> {
  String username;
  String useremail;
  String userpw;
  String errormessage = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Image(
              image: AssetImage('logo.png'),
              width: 70.0,
            ),
            SizedBox(
              height: 10.0,
            ),
            Container(
              child: Text('Create Account'),
            ),
            SizedBox(
              height: 15.0,
            ),
            Container(
              width: 300.0,
              child: TextField(
                  obscureText: false,
                  onChanged: (value) {
                    username = value;
                  }),
            ),
            SizedBox(
              height: 8.0,
            ),
            Container(
              width: 300.0,
              child: TextField(
                  obscureText: false,
                  onChanged: (value) {
                    useremail = value;
                  }),
            ),
            SizedBox(
              height: 8.0,
            ),
            Container(
              width: 300.0,
              child: TextField(
                  obscureText: true,
                  onChanged: (value) {
                    userpassword = value;
                  }),
            ),
            SizedBox(
              height: 8.0,
            ),
            Container(
              child: Text(
                errormessage,
                style: TextStyle(color: Colors.red[500]),
              ),
            ),
            SizedBox(height: 12.0),
            Container(
              margin: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
              child: ElevatedButton(
                onPressed: () {

                  Map json = {
                    "username": username,
                    "useremail": useremail,
                    "userpw": userpw,
                  };
                  //print(json);

                  UserSignUp(json).then((result) {
                    if (result['error'] != null) {
                      setState(() {
                        errormessage = result['error'];
                      });
                    } else {
                      setState(() {
                        errormessage = '';
                      });
                      Navigator.push(context,
                          MaterialPageRoute(builder: (context) => SignInPage()));
                    }
                  });
                },
                style: ElevatedButton.styleFrom(
                  primary: Color(0xff04A148C),
                  onPrimary: Colors.blue[900],
                  padding: EdgeInsets.only(
                      left: 70.0, top: 10.0, right: 70.0, bottom: 10.0),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10.0),
                  ),
                ),
                child: Text(
                  'Sign Up',
                  style: TextStyle(
                    color: Colors.white,
                    fontFamily: 'Roboto',
                    fontSize: 15.0,
                    fontWeight: FontWeight.w600,
                    letterSpacing: 1.0,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}




DART FILE OF CONTROLLER BELOW:

final appkey ="appkey random numbers";

Future<Map> UserSignUp(Map json) async {
  json['appkey'] = appkey;
  final response = await http.post(
    Uri.parse('Sign Up URL'),
    headers: <String, String>{
      'Content Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(json),
  );

  print(response.body);
  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else if (response.statusCode == 401) {
    Map error = jsonDecode(response.body);
    Map json = {
      "error": error['data'][0]['msg'],
    };

    return json;
  } else {
    throw Exception('Fail');
  }
}

Future<Map> UserSignIn(Map json) async {
  json['appkey'] = appkey;
  final response = await http.post(
    Uri.parse('Sign Up URL'),
    headers: <String, String>{
      'Content Type': 'application/json;charset=UTF-8',
    },
    body: jsonEncode(json),
  );


  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else if (response.statusCode == 400) {
    return jsonDecode(response.body);
  } else {
    throw Exception('Fail');
  }
}

【问题讨论】:

    标签: flutter flutter-dependencies flutter-test


    【解决方案1】:

    Content-Type 有一个连字符。在标题中添加一个。

    【讨论】:

    • 您好 user3486184,感谢您的快速回复。我添加了连字符,控制台中的消息略有变化。它仍然有 和 [ERROR:flutter/lib/ui/ui_dart_state.cc(213)] 未处理的异常:类型 'String' 不是类型 'FutureOr>'
    • 你好@Khushal Jangid,它指向:Map error = jsonDecode(response.body);返回错误['data'][0]['msg'];
    • 你好@KhushalJangid,我在上面的代码sn-ps中添加了flutter run console消息,供大家参考。我的目标是让错误通知出现在注册按钮上方,当我用空文本字段按下它但没有出现错误通知时。如果我确实输入了一些详细信息,它也不会进入登录页面,谢谢您的回复。 ^_^
    • 嗨@KhushalJangid,是的,您可以在“控制器的DART文件”下的代码sn-p中看到它。我不确定是什么导致了该错误,因为它不是标志。你能建议我如何纠正它吗?谢谢。
    【解决方案2】:

    我明白了,你需要使用awaitjsonDecode 函数,因为它是一个未来。 例如:

    Map res = await jsonDecode(response.body);
    return res;
    

    替换:

    final appkey ="appkey random numbers";
    
    Future<Map> UserSignUp(Map json) async {
      json['appkey'] = appkey;
      final response = await http.post(
        Uri.parse('Sign Up URL'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(json),
      );
    
      print(response.body);
      if (response.statusCode == 200) {
        return jsonDecode(response.body);
      } else if (response.statusCode == 401) {
        Map error = jsonDecode(response.body);
        Map json = {
          "error": error['data'][0]['msg'],
        };
    
        return json;
      } else {
        throw Exception('Fail');
      }
    }
    
    Future<Map> UserSignIn(Map json) async {
      json['appkey'] = appkey;
      final response = await http.post(
        Uri.parse('Sign Up URL'),
        headers: <String, String>{
          'Content-Type': 'application/json;charset=UTF-8',
        },
        body: jsonEncode(json),
      );
    
    
      if (response.statusCode == 200) {
        return jsonDecode(response.body);
      } else if (response.statusCode == 400) {
        return jsonDecode(response.body);
      } else {
        throw Exception('Fail');
      }
    }
    

    与:

    final appkey ="appkey random numbers";
    
    Future<Map> UserSignUp(Map json) async {
      json['appkey'] = appkey;
      final response = await http.post(
        Uri.parse('Sign Up URL'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(json),
      );
    
      print(response.body);
      if (response.statusCode == 200) {
        Map data = await jsonDecode(response.body);
        return data;
      } else if (response.statusCode == 401) {
        Map error = await jsonDecode(response.body);
        Map json = {
          "error": error['data'][0]['msg'],
        };
    
        return json;
      } else {
        throw Exception('Fail');
      }
    }
    
    Future<Map> UserSignIn(Map json) async {
      json['appkey'] = appkey;
      final response = await http.post(
        Uri.parse('Sign Up URL'),
        headers: <String, String>{
          'Content-Type': 'application/json;charset=UTF-8',
        },
        body: jsonEncode(json),
      );
    
    
      if (response.statusCode == 200) {
        Map data = await jsonDecode(response.body);
        return data;
      } else if (response.statusCode == 400) {
        Map data = await jsonDecode(response.body);
        return data;
      } else {
        throw Exception('Fail');
      }
    }
    

    【讨论】:

    • 你好@KhushalJangid,想问一下我需要在哪里添加它?谢谢。
    • 嘿@dstacklurker,您需要在两个异步函数UserSignUp和UserSignIn中添加这个,以便在使用之前解码响应正文!
    • 嗨@KhushalJangid,我必须将它单独添加到控制器飞镖文件中的两个异步中?在哪个部位?提前致谢。
    • 嘿,@dstacklurker,检查更新的答案
    • 嗨 KhushalJangid,我能够让它与 Map 错误一起工作,而不是 Map json 代码行。我尝试了您的代码,即使文本字段为空,它也会使注册页面转到登录页面。所以错误通知不会出现。但是建议的代码对于测试屏幕流程很有用。不过,感谢您的回复。 ^_^
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2020-04-12
    • 2022-11-20
    • 2021-09-08
    • 2023-01-12
    • 2020-02-14
    • 1970-01-01
    相关资源
    最近更新 更多