【问题标题】:Unhandled Exception: NoSuchMethodError: The getter 'length' was called on null未处理的异常:NoSuchMethodError:在 null 上调用了 getter 'length'
【发布时间】:2020-06-23 11:24:59
【问题描述】:

想要在接收来自服务器端的响应时登录应用程序,我创建了两个文本字段,我希望它在收到 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));
    }
    }
?>

【问题讨论】:

  • 什么时候出现这个错误?如果您分享错误行会有所帮助吗?保存时会出现这种情况吗?
  • 因为我在onpressed中应用了userinputValidation函数,所以我无法理解原因。
  • 我认为在你的代码中你试图获取 List 的空引用的长度,分享错误的行

标签: flutter dart


【解决方案1】:

在上面的代码中,NoSuchMethodError 被抛出,因为一些字段被填充为 null,当调用 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(),
    };
  } 

这是用户类的最终版本

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

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 2022-01-16
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 2020-09-28
    • 1970-01-01
    相关资源
    最近更新 更多