Reputation: 87
want to login to the application while receiving a response from the server-side, I have create two text field and I want it to display invalid values after receiving 0 status and navigate to next page on status 1. I have created a user class having an object with the name status which receives status values from the server-side. But the fact is that after implementing and calling the object into the login page receiving the error.
Unhandled Exception: NoSuchMethodError: The getter 'length' was called on null.
E/flutter (29946): Receiver: null
E/flutter (29946): Tried calling: length
I don't know the reason if someone understands, I would definitely appreciate the answer. Thank You!
Login page Code:
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:login_page_flutter/Models/pages/user_profile.dart';
import 'Models/myconstant.dart';
import 'Models/user.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
TextEditingController txtusername = TextEditingController();
TextEditingController txtpassword = TextEditingController();
bool isUploading = false;
bool validation = false;
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
isUploading = false;
return Scaffold(
appBar: AppBar(
elevation: 0,
brightness: Brightness.light,
backgroundColor: Colors.white,
leading: IconButton(
icon: Icon(Icons.arrow_back, size: 20, color: Colors.pink[80]),
onPressed: () {
Navigator.pop(context);
}),
),
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(20.0),
child: ListView(
children: <Widget>[
SizedBox(height: 10),
SizedBox(height: 10),
Card(
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
errorText: validation ? 'Must Fill Input Field' : null,
border: InputBorder.none,
hintText: "Enter UserName",
hintStyle: TextStyle(
fontSize: 12,
color: Colors.pink[800].withOpacity(0.5),
),
),
controller: txtusername,
),
TextField(
obscureText: true,
decoration: InputDecoration(
errorText: validation ? 'Must Fill Input Field' : null,
border: InputBorder.none,
hintText: "Enter Password",
hintStyle: TextStyle(
fontSize: 12,
color: Colors.pink[800].withOpacity(0.5),
),
),
controller: txtpassword,
),
],
),
),
SizedBox(height: 20),
Center(
child: AnimatedContainer(
duration: const Duration(
milliseconds: 50,
),
child: getWidgetByStatus(),
),
),
],
),
),
),
);
}
Future<void> saveData(dynamic jsonOfUser) async {
setState(() {
isUploading = true;
});
await Future.delayed(Duration(seconds: MyConstant.VAL_SECONDS), () {});
return post(
MyConstant.URL_USER_INSERT_LOGIN,
body: jsonOfUser,
).then((onRecievedResponse) {
print(onRecievedResponse.body);
setState(() {
isUploading = false;
});
return null;
});
}
Widget getWidgetByStatus() {
if (isUploading) {
return CircularProgressIndicator(
backgroundColor: Colors.pink,
);
} else {
return RaisedButton(
onPressed: () {
User user = User(
username: txtusername.text,
password: txtpassword.text,
type: 11,
);
saveData(User.toJson(user));
checkValidationOfData();
userInputValidation();
},
child: Text('Submit'),
);
}
}
void checkValidationOfData() {
setState(() {
if (txtusername.text.isEmpty) {
return validation = true;
}
if (txtpassword.text.isEmpty) {
return validation = true;
} else {
return validation = false;
}
});
}
void userInputValidation() {
if (validation == false) {
if (User.Key_status == '0') {
setState(() {
return 'Invalid Values';
});
} else if (User.Key_status == '1') {
setState(() {
return Navigator.push(context, MaterialPageRoute(builder: (context) {
return UserProfile();
}));
});
}
}
}
}
class User:
class User {
int id;
static const String Key_id = 'id';
String name;
static const String Key_name = 'name';
String username;
static const String Key_username = 'username';
String password;
static const String Key_password = 'password';
int type;
static const String Key_type = 'type';
int status;
static const String Key_status = 'status';
User({
this.id,
this.name,
this.username,
this.password,
this.type,
});
static Map<String, String> toJson(User user) {
return {
Key_id: user.id.toString(),
Key_name: user.name,
Key_username: user.username,
Key_password: user.password,
Key_type: user.type.toString(),
};
}
static List<User> fromJsonArray(dynamic jsonArray) {
List<User> listOfUserDetail = List<User>();
for (var jsonObject in jsonArray) {
User newUser = User();
newUser.status = jsonObject[Key_status];
listOfUserDetail.add(newUser);
}
return listOfUserDetail;
}
}
Files for server-side connection
class MyConstant {
static const String BASE_URL_ = 'http://23e30b0d5027.ngrok.io/';
static const String URL_API = BASE_URL_ + 'fyp/';
static const String URL_USER_INSERT = URL_API + 'user_signup.php';
static const String URL_USER_INSERT_LOGIN = URL_API + 'user_login.php';
static const int VAL_SECONDS = 0;
}
php code
<?php
require_once('conn.php');
$username=$_POST['username'];
$password=$_POST['password'];
$query="SELECT * FROM user WHERE username='$username' and password='$password'";
$query_result= mysqli_query($con,$query);
$count= mysqli_num_rows($query_result);
if($query_result){
$array_of_records = array();
if($count>0) {
while ($row = mysqli_fetch_assoc($query_result)) {
$obj= array(
"id"=> $row['id'],
"name"=> $row['name'],
"username"=> $row['username'],
"password"=> $row['password'],
"type"=> $row['type'],
);
array_push($array_of_records, $obj);
}
echo json_encode(array('status'=>1, 'data'=> $array_of_records));
}
else
{
echo json_encode(array('status'=>0, 'data'=> $array_of_records));
}
}
?>
Upvotes: 0
Views: 1938
Reputation: 2260
In the above code the NoSuchMethodError is being thrown because some fields are getting populated as null, and this when the saveData method is called the jsonUser being passed is something like this -
{
id: null,
name: null,
username: sample,
password: sample,
type: 11
}
Thus when the saveData() tries to call the http.post method with the given user data it will try to encode the user into a JSON representation thus encountering NoSuchMethodError while checking the length of the data being serialized.
You can update the the User class with toJSON method to handle such null cases,
static Map<String, String> toJson(User user) {
return {
Key_id: user.id != null ? user.id.toString() : '',
Key_name: user.name ?? '',
Key_username: user.username,
Key_password: user.password,
Key_type: user.type.toString(),
};
}
Here is the final version of User class
class User {
int id;
static const String Key_id = 'id';
String name;
static const String Key_name = 'name';
String username;
static const String Key_username = 'username';
String password;
static const String Key_password = 'password';
int type;
static const String Key_type = 'type';
int status;
static const String Key_status = 'status';
User({
this.id,
this.name,
this.username,
this.password,
this.type,
});
static Map<String, String> toJson(User user) {
return {
Key_id: user.id != null ? user.id.toString() : '',
Key_name: user.name ?? '',
Key_username: user.username,
Key_password: user.password,
Key_type: user.type.toString(),
};
}
static List<User> fromJsonArray(dynamic jsonArray) {
List<User> listOfUserDetail = List<User>();
for (var jsonObject in jsonArray) {
User newUser = User();
newUser.status = jsonObject[Key_status];
listOfUserDetail.add(newUser);
}
return listOfUserDetail;
}
}
Hope this helps!
Upvotes: 1