我试图在颤动中发出一个简单的 POST 请求并尝试捕获异常。我在控制台中看到异常,但是当我在 FutureBuilder 中执行 print(snapshot.hasError) 时,它给了我错误。
因为,我是新来的,我不知道我错过了哪一部分。现在被困在这里一段时间了。
这是我在 service.dart 中的 post 功能
Future <dynamic> postData(String url, dynamic data) async {
try {
final response = await post(_baseUrl + url, body: data);
if (response.statusCode == 200) {
return json.decode(response.body);
} else {
throw Exception('Failed to load data');
}
} catch (e) {
throw Exception(e);
}
}
在我的 UI 设计课程中,我首先设置了显示输入文本字段(姓名和电子邮件)的条件,一旦用户填写了他的输入详细信息,我将显示 FutureBuilder 小部件。
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stationary/components/error_dialog.dart';
import 'package:stationary/services/base_helper.dart';
import 'package:stationary/services/signup_services.dart';
import 'package:stationary/size_config.dart';
import 'package:stationary/components/spacer.dart';
import '../../constants.dart' as Constants;
class InputUserDetails extends StatefulWidget {
// final String userMobile;
@override
_InputUserDetailsState createState() => _InputUserDetailsState();
}
class _InputUserDetailsState extends State<InputUserDetails> {
TextEditingController nameController = TextEditingController();
TextEditingController emailController = TextEditingController();
bool isButtonDisabled = true;
bool showLoader = false;
Future<dynamic> futureList;
final storage = new FlutterSecureStorage();
String _mobileNum;
void checkButtonDisability(value) {
var name = nameController.text;
var email = emailController.text;
if (name.length > 0 && email.length > 0) {
setState(() {
isButtonDisabled = false;
});
} else {
setState(() {
isButtonDisabled = true;
});
}
}
@override
void initState() {
super.initState();
_getMobileNumber();
}
_getMobileNumber() async {
var tempMobileNum = await storage.read(key: 'userMobile');
setState(() {
_mobileNum = tempMobileNum;
});
}
signUpUser(name, email) async {
String endpoint = Constants.postUserInfo;
var json = {
"email": email,
"name": name,
"phone_number": _mobileNum
};
print(json);
futureList = await ApiBaseHelper().postData(endpoint, json);
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
resizeToAvoidBottomInset: false,
body: showLoader? FutureBuilder(
future: futureList,
builder: (context, snapshot) {
// print(snapshot.hasData); // ================= false
// print(snapshot.hasError); // ================ false
if(snapshot.hasData) {
print(snapshot.data);
return Container();
} else if(snapshot.hasError) {
print(snapshot.error);
return ErrorDialog('Some error occurred');
}
return CircularProgressIndicator();
},
) : Container(
margin: EdgeInsets.all(SizeConfig.safeBlockHorizontal * 5),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: SizeConfig.safeBlockVertical * 10,
),
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Enter your details',
style: TextStyle(
fontWeight: FontWeight.w500,
fontFamily: 'Roboto',
fontSize: SizeConfig.safeBlockHorizontal * 5,
color: Colors.white,
),
),
Container(
child: SpacerElement(),
),
],
),
),
SizedBox(
height: SizeConfig.safeBlockVertical * 2,
),
SizedBox(height: SizeConfig.safeBlockVertical * 10, ),
Flexible(
child: TextFormField(
style: TextStyle(
fontWeight: FontWeight.w500,
fontFamily: 'Roboto',
fontSize: SizeConfig.safeBlockHorizontal * 4,
color: Colors.white,
),
onChanged: (value) {
checkButtonDisability(value);
},
cursorColor: Colors.white,
controller: nameController,
keyboardType: TextInputType.text,
decoration: new InputDecoration(
hintText: 'Enter Your Name',
hintStyle: TextStyle(
color: Colors.white30,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
),
contentPadding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
isDense: true,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
),
),
SizedBox(height: SizeConfig.safeBlockVertical * 5, ),
Flexible(
child: TextFormField(
style: TextStyle(
fontWeight: FontWeight.w500,
fontFamily: 'Roboto',
fontSize: SizeConfig.safeBlockHorizontal * 4,
color: Colors.white,
),
onChanged: (value) {
checkButtonDisability(value);
},
cursorColor: Colors.white,
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: new InputDecoration(
hintText: 'Enter Your Email',
hintStyle: TextStyle(
color: Colors.white30,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
),
contentPadding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
isDense: true,
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
),
),
SizedBox(height: SizeConfig.safeBlockVertical * 5, ),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
),
child: FlatButton(
padding: EdgeInsets.symmetric(
horizontal: SizeConfig.safeBlockHorizontal * 5,
vertical: SizeConfig.safeBlockVertical * 2
),
color: isButtonDisabled ? Theme.of(context).primaryColor : Theme.of(context).buttonColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
onPressed: isButtonDisabled? () {} : () {
var email = emailController.text;
var name = nameController.text;
var flag = RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email);
if(!flag) {
showDialog(context: context, child: ErrorDialog('Please enter a valid email'));
} else {
setState(() {
showLoader = true;
});
signUpUser(name, email);
}
// Navigator.push(context, MaterialPageRoute(builder: (context) => SearchMapsScreen()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'TAKE ME IN',
style: TextStyle(
fontWeight: FontWeight.w500,
fontFamily: 'Roboto',
color: isButtonDisabled ? Colors.white60 : Colors.black,
fontSize: SizeConfig.safeBlockHorizontal * 4,
),
),
],
),
),
),
],
),
),
),
);
}
}
请建议我在哪里遗漏了什么,以及这是否是使用输入文本处理 Future Builder 小部件和 Column 小部件的正确方法。
任何帮助,将不胜感激。
提前致谢!