#json #flutter #dart
#json #flutter #dart
Вопрос:
Я пытаюсь создать вход пользователя с использованием flutter и серверной части в php. Но при обработке данных json при действительном входе в систему flutter выдает ошибку: «тип ‘_OneByteString’ не является подтипом типа int». Но, как ни странно, при вводе неправильного адреса электронной почты или пароля ошибка не появляется, и отображается панель закусок, но индикатор прогресса продолжает отображаться бесконечно. Я не могу понять проблему, поскольку в обоих случаях строка возвращается как статус. Пожалуйста, помогите мне. Я застрял здесь на 2 дня. Вот мой код flutter:
Future<Login> userLogin(String email, String password) async {
Map<String, dynamic> map = {'email': email, 'password': password};
final http.Response response = await http.post(
'my php page',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(map),
);
if (response.statusCode == 201 || response.statusCode == 200) {
return Login.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to login.');
}
}
class Login {
final int usrid;
//final String usrname;
final String status;
Login({this.usrid, this.status});
factory Login.fromJson(Map<String, dynamic> json) {
return Login(usrid: json['usrid'], status: json['type']);
}
}
class TextControl extends StatefulWidget {
TextControl({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _TextControl();
}
}
class _TextControl extends State<TextControl> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _controller = TextEditingController();
final TextEditingController _controller2 = TextEditingController();
@override
void dispose() {
// Clean up the controller when the widget is disposed.
_controller.dispose();
_controller2.dispose();
super.dispose();
}
Future<Login> _futureLogin;
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: (_futureLogin == null)
? Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: _controller,
decoration: InputDecoration(hintText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value.isEmpty || !value.isValidEmail()) {
return 'Please enter valid email.';
}
return null;
},
),
TextFormField(
controller: _controller2,
decoration: InputDecoration(hintText: 'Password'),
obscureText: true,
validator: (value) {
if (value.isEmpty) {
return 'Please enter password.';
}
return null;
},
),
Container(
margin: EdgeInsets.all(10.0),
child: RaisedButton(
color: Colors.purple[400],
textColor: Colors.white,
onPressed: () {
if (_formKey.currentState.validate()) {
setState(() {
_futureLogin =
userLogin(_controller.text, _controller2.text);
});
}
},
child: Text('Login', style: TextStyle(fontSize: 18.0)),
),
),
],
)
: FutureBuilder<Login>(
future: _futureLogin,
builder: (context, snapshot) {
if (snapshot.hasData) {
//return Text(snapshot.data.usrname);
if (snapshot.data.status == '1') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => TextInput()),
);
} else if (snapshot.data.status == '2') {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Invalid login credentials.')));
}
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Center(child: CircularProgressIndicator());
},
),
);
}
}
Я вернул строку ‘1’ для действительного входа и строку ‘2’ для неверного входа. Итак, почему ошибка возникает только при действительном входе? И для неверного входа отображается сообщение «Неверные учетные данные», но индикатор прогресса не останавливается. Как я могу остановить это и показать экран входа в систему? Пожалуйста, помогите мне в отношении 2 проблем. Заранее спасибо.
Комментарии:
1. И когда логин действителен, идентификатор пользователя возвращается в json[‘usrid’], который является int, а для неверного входа json[‘usrid’] равен 0, что также является int. Это потому, что я использовал final int usrid; в классе Login.
2.
CircularProgressIndicator
Не исчезает, потому что вы ничего не возвращаете, когдаsnapshot.data.status = '2'
, поэтому по умолчанию индикатор возвращается снова.3. И что касается ошибки успешного входа, я подозреваю, что возвращаемое значение для
json['usrId']
на самом деле не является int, как вы полагаете, а на самом деле является строкой. Выведите строку JSON ответа, чтобы убедиться в том, что вы на самом деле получаете от сервера.4. Вы не можете вернуть null, поскольку функция builder должна что-то возвращать. Если вы не хотите ничего возвращать, то функция builder не подходит для этого кода.
5. Я считаю, что
_OneByteString
и_Smi
являются внутренними типами для анализатора JSON, представляющими (в двух словах) строковое значение и целочисленное значение соответственно. Это говорит мне о том, что ваш сервер PHP, вероятно, имеет ошибку и возвращаетint
для идентификатора пользователя при неудачном входе в систему иString
для идентификатора пользователя при успешном входе в систему. Вам нужно будет отследить и исправить эту ошибку, чтобы ваша сторона Flutter работала должным образом.