未处理的异常:NoSuchMethodError:在null上调用了getter'length'

时间:2020-06-23 11:24:59

标签: flutter dart

想要从服务器端接收响应时登录到应用程序,我创建了两个文本字段,我希望它在收到0状态后显示无效值,并导航到状态1的下一页。我创建了一个用户类,其对象的名称为status,该对象从服务器端接收状态值。但是事实是,实现并调用该对象到登录页面后,会收到错误。

 Unhandled Exception: NoSuchMethodError: The getter 'length' was called on null.
E/flutter (29946): Receiver: null
E/flutter (29946): Tried calling: length  

我不知道有人理解的原因,我一定会很感激的。谢谢!

登录页面代码:

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 {
  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;
  }
}

用于服务器端连接的文件

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代码

<?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));
    }
    }
?>

1 个答案:

答案 0 :(得分:1)

在上面的代码中,由于某些字段被填充为null,因此引发NoSuchMethodError,并且在调用saveData方法时,传递的jsonUser就是这样-

{
  id: null, 
  name: null, 
  username: sample, 
  password: sample, 
  type: 11
}

因此,当saveData()尝试使用给定的用户数据调用http.post方法时,它将尝试将用户编码为JSON表示形式,从而在检查序列化数据的长度时遇到NoSuchMethodError。

您可以使用toJSON方法更新User类以处理此类空情况,

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(),
    };
  } 

这是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 != 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;
  }
}

希望这会有所帮助!