フラッターで単純な POST リクエストを作成しようとしていて、例外をキャッチしようとしています。コンソールに例外が表示されますが、FutureBuilder 内で print(snapshot.hasError) を実行すると、false になります。
私はフラッターに慣れていないので、どの部分が欠けているのかわかりません。しばらくここで立ち往生しています。
これがservice.dartのポスト関数です
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 ウィジェットと列ウィジェットを入力テキストで処理する正しい方法であるかどうかも教えてください。
どんな助けでも大歓迎です。
前もって感謝します!