post http 请求:在 null flutter 上调用 getter 'length'

May*_*iXx 4 mobile android flutter flutter-layout

我想在调用 API 时创建一个用户。\n我使用 URL 创建了一个 Future,并在屏幕页面中调用我的模型。\n我在表单中获取了所有数据,但当我调用 API 时,出现以下错误:

\n\n

getter \'length\' 被调用为 null...

\n\n

用户模型:

\n\n
class Candidate {\n  int id;\n  String firstname;\n  String lastname;\n  String email;\n\n  Candidate({this.id, this.firstname, this.lastname, this.email});\n\n  factory Candidate.fromJson(Map<String, dynamic> json) {\n    return Candidate(\n      id: json[\'id\'],\n      firstname: json[\'firstname\'],\n      lastname: json[\'lastname\'],\n      email: json[\'email\'],\n    );\n  }\n\n  Map toMap() {\n    var map = new Map<String, dynamic>();\n    map["id"] = id;\n    map["firstname"] = firstname;\n    map["lastname"] = lastname;\n    map["email"] = email;\n    return map;\n  }\n\n  Future<Candidate> candidateAuth({Map body}) async {\n    String url = \'http://10.0.2.2:3000/v1/api/auth/candidate\';\n    final response = await http.post(url, body: body, headers: {"Accept": "application/json"});\n\n    if (response.statusCode == 201) {\n      return Candidate.fromJson(json.decode(response.body));\n    } else {\n      throw Exception(\'Failed auth\');\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑 :

\n\n

我修改后添加了登录页面的所有代码。

\n\n

在登录页面中:

\n\n
import \'package:blackbox/models/candidate_model.dart\';\nimport \'package:blackbox/screens/theme_page.dart\' as t;\nimport \'package:flutter/material.dart\';\n\nclass Login extends StatefulWidget {\n  @override\n  State<StatefulWidget> createState() {\n    return new _Login();\n  }\n}\n\nclass _Login extends State<Login> {\n  final _formKey = GlobalKey<FormState>();\n  String email, lastname, firstname;\n\n  @override\n  Widget build(BuildContext context) {\n    return new Scaffold(\n      appBar: new AppBar(\n        leading: Image.asset(\n          \'assets/img/logo_ineat.png\',\n          fit: BoxFit.contain,\n          height: 32,\n        ),\n        title: Text(\'BlackBox\'),\n      ),\n      body: new Center(\n        child: new SingleChildScrollView(\n          child: new Column(\n            mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n            children: <Widget>[\n              new Container(\n                margin: EdgeInsets.only(top: 10.0, bottom: 20.0),\n                alignment: Alignment.topCenter,\n                child: new Text(\'Se Connecter\',\n                    style: new TextStyle(\n                        fontSize: 24, fontWeight: FontWeight.bold)),\n              ),\n              new Card(\n                elevation: 10,\n                color: Colors.pink,\n                child: new Container(\n                  width: MediaQuery.of(context).size.width / 2,\n                  height: MediaQuery.of(context).size.height / 3,\n                  child: new Image.asset(\'assets/img/logo_ineat.png\',\n                      fit: BoxFit.contain),\n                ),\n              ),\n              new Form(\n                key: _formKey,\n                child: new Column(\n                  children: <Widget>[\n                    new Row(\n                      children: <Widget>[\n                        new Container(\n                          width: MediaQuery.of(context).size.width / 5,\n                          margin:\n                              EdgeInsets.only(left: 10, top: 5, right: 10.0),\n                          child: new Text("Nom : "),\n                        ),\n                        new Container(\n                          width: MediaQuery.of(context).size.width / 1.4,\n                          margin: EdgeInsets.only(top: 5, right: 10.0),\n                          child: new TextFormField(\n                            keyboardType: TextInputType.text,\n                            decoration: new InputDecoration(\n                                labelText: \'Entrez votre nom\'),\n                            validator: (value) {\n                              if (value.isEmpty) {\n                                return \'Veuillez remplir le champ nom\';\n                              }\n                              lastname = value;\n                              return null;\n                            },\n                          ),\n                        ),\n                      ],\n                    ),\n                    new Row(\n                      children: <Widget>[\n                        new Container(\n                          width: MediaQuery.of(context).size.width / 5,\n                          margin:\n                              EdgeInsets.only(left: 10, top: 5, right: 10.0),\n                          child: new Text("Pr\xc3\xa9nom : "),\n                        ),\n                        new Container(\n                          width: MediaQuery.of(context).size.width / 1.4,\n                          margin: EdgeInsets.only(top: 5, right: 10.0),\n                          child: new TextFormField(\n                            keyboardType: TextInputType.text,\n                            decoration: new InputDecoration(\n                                labelText: \'Entrez votre pr\xc3\xa9nom\'),\n                            validator: (value) {\n                              if (value.isEmpty) {\n                                return \'Veuillez remplir le champ pr\xc3\xa9nom\';\n                              }\n                              firstname = value;\n                              return null;\n                            },\n                          ),\n                        ),\n                      ],\n                    ),\n                    new Row(\n                      children: <Widget>[\n                        new Container(\n                          width: MediaQuery.of(context).size.width / 5,\n                          margin:\n                              EdgeInsets.only(left: 10, top: 5, right: 10.0),\n                          child: new Text("Email : "),\n                        ),\n                        new Container(\n                          width: MediaQuery.of(context).size.width / 1.4,\n                          margin: EdgeInsets.only(top: 5, right: 10.0),\n                          child: new TextFormField(\n                            keyboardType: TextInputType.emailAddress,\n                            decoration: new InputDecoration(\n                                labelText: \'Entrez votre email\'),\n                            validator: (value) {\n                              if (value.isEmpty) {\n                                return \'Veuillez remplir le champ email\';\n                              }\n                              email = value.toLowerCase();\n                              return null;\n                            },\n                          ),\n                        ),\n                      ],\n                    ),\n                    new Container(\n                      margin: EdgeInsets.only(top: 30, bottom: 5, right: 10.0),\n                      alignment: Alignment.bottomRight,\n                      child: new RaisedButton.icon(\n                          onPressed: () {\n                            setState(() async {\n                              if (_formKey.currentState.validate()) {\n                                Candidate newPost = new Candidate(\n                                  lastname: lastname,\n                                  firstname: firstname,\n                                  email: email,\n                                );\n                                var candidate = await Candidate()\n                                    .candidateAuth(body: newPost.toMap());\n                              }\n                            });\n                          },\n                          icon: Icon(Icons.check),\n                          label: Text(\'Valider\')),\n                    ),\n                  ],\n                ),\n              ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误信息:

\n\n
\n

发生异常。
\n NoSuchMethodError(NoSuchMethodError:在 null 上调用 getter \'length\'。\n 接收者:null 尝试调用:\n length)处理手势时抛出以下断言:\n setState() 回调参数返回 Future 。_Login#e2125 上的 setState() 方法是使用返回 Future 的闭包或方法调用的。\n 也许它被标记为“异步”。不要在 setState() 调用中执行异步工作,而是首先执行工作(不更新小部件状态),然后在 setState() 调用中同步更新状态

\n
\n

May*_*iXx 6

它是 :

headers: {'Content-type': 'application/json','Accept': 'application/json'}
Run Code Online (Sandbox Code Playgroud)