我想在调用 API 时创建一个用户。 我用 URL 创建了一个未来,并在屏幕页面中调用我的模型。 我在我的表单中获取所有数据,但是当我调用我的 API 时,我遇到此错误:
获取器"长度"在空时被调用...
用户型号 :
class Candidate {
int id;
String firstname;
String lastname;
String email;
Candidate({this.id, this.firstname, this.lastname, this.email});
factory Candidate.fromJson(Map<String, dynamic> json) {
return Candidate(
id: json['id'],
firstname: json['firstname'],
lastname: json['lastname'],
email: json['email'],
);
}
Map toMap() {
var map = new Map<String, dynamic>();
map["id"] = id;
map["firstname"] = firstname;
map["lastname"] = lastname;
map["email"] = email;
return map;
}
Future<Candidate> candidateAuth({Map body}) async {
String url = 'http://10.0.2.2:3000/v1/api/auth/candidate';
final response = await http.post(url, body: body, headers: {"Accept": "application/json"});
if (response.statusCode == 201) {
return Candidate.fromJson(json.decode(response.body));
} else {
throw Exception('Failed auth');
}
}
}
编辑:
我添加了修改后的登录页面的所有代码。
在登录页面中:
import 'package:blackbox/models/candidate_model.dart';
import 'package:blackbox/screens/theme_page.dart' as t;
import 'package:flutter/material.dart';
class Login extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _Login();
}
}
class _Login extends State<Login> {
final _formKey = GlobalKey<FormState>();
String email, lastname, firstname;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
leading: Image.asset(
'assets/img/logo_ineat.png',
fit: BoxFit.contain,
height: 32,
),
title: Text('BlackBox'),
),
body: new Center(
child: new SingleChildScrollView(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Container(
margin: EdgeInsets.only(top: 10.0, bottom: 20.0),
alignment: Alignment.topCenter,
child: new Text('Se Connecter',
style: new TextStyle(
fontSize: 24, fontWeight: FontWeight.bold)),
),
new Card(
elevation: 10,
color: Colors.pink,
child: new Container(
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 3,
child: new Image.asset('assets/img/logo_ineat.png',
fit: BoxFit.contain),
),
),
new Form(
key: _formKey,
child: new Column(
children: <Widget>[
new Row(
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width / 5,
margin:
EdgeInsets.only(left: 10, top: 5, right: 10.0),
child: new Text("Nom : "),
),
new Container(
width: MediaQuery.of(context).size.width / 1.4,
margin: EdgeInsets.only(top: 5, right: 10.0),
child: new TextFormField(
keyboardType: TextInputType.text,
decoration: new InputDecoration(
labelText: 'Entrez votre nom'),
validator: (value) {
if (value.isEmpty) {
return 'Veuillez remplir le champ nom';
}
lastname = value;
return null;
},
),
),
],
),
new Row(
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width / 5,
margin:
EdgeInsets.only(left: 10, top: 5, right: 10.0),
child: new Text("Prénom : "),
),
new Container(
width: MediaQuery.of(context).size.width / 1.4,
margin: EdgeInsets.only(top: 5, right: 10.0),
child: new TextFormField(
keyboardType: TextInputType.text,
decoration: new InputDecoration(
labelText: 'Entrez votre prénom'),
validator: (value) {
if (value.isEmpty) {
return 'Veuillez remplir le champ prénom';
}
firstname = value;
return null;
},
),
),
],
),
new Row(
children: <Widget>[
new Container(
width: MediaQuery.of(context).size.width / 5,
margin:
EdgeInsets.only(left: 10, top: 5, right: 10.0),
child: new Text("Email : "),
),
new Container(
width: MediaQuery.of(context).size.width / 1.4,
margin: EdgeInsets.only(top: 5, right: 10.0),
child: new TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: new InputDecoration(
labelText: 'Entrez votre email'),
validator: (value) {
if (value.isEmpty) {
return 'Veuillez remplir le champ email';
}
email = value.toLowerCase();
return null;
},
),
),
],
),
new Container(
margin: EdgeInsets.only(top: 30, bottom: 5, right: 10.0),
alignment: Alignment.bottomRight,
child: new RaisedButton.icon(
onPressed: () {
setState(() async {
if (_formKey.currentState.validate()) {
Candidate newPost = new Candidate(
lastname: lastname,
firstname: firstname,
email: email,
);
var candidate = await Candidate()
.candidateAuth(body: newPost.toMap());
}
});
},
icon: Icon(Icons.check),
label: Text('Valider')),
),
],
),
),
],
),
),
),
);
}
}
错误信息:
发生异常。
NoSuchMethodError (NoSuchMethodError: getter 'length' 被调用在 null 上。 接收器:空 已尝试呼叫: 长度(在处理手势时抛出以下断言: setState(( 回调参数返回了一个 Future。 setState(( 方法 在 _Login#e2125 上,使用返回 Future 的闭包或方法调用。 也许它被标记为"异步"。而不是表演 调用 setState(( 中的异步工作,首先执行工作 (不更新小组件状态(,然后同步更新 调用 setState(( 中的状态
它是:
headers: {'Content-type': 'application/json','Accept': 'application/json'}
因为candidateAuth
返回未来,所以你需要添加await
:
Candidate newPost = new Candidate(
lastname: lastname,
firstname: firstname,
email: email,
);
var candidate = await Candidate().candidateAuth(body: newPost.toMap());
上级:
根据错误消息,从setState
中删除async
:
onPressed: () async {
if (_formKey.currentState.validate()) {
Candidate newPost = new Candidate(
lastname: lastname,
firstname: firstname,
email: email,);
var candidate = await Candidate().candidateAuth(body: newPost.toMap());
setState(() {
// do what you need with candidate here
});
}
},