Метод получения, возвращающий нулевое значение - PullRequest
0 голосов
/ 08 мая 2020

Я разработал страницу входа, используя локальную базу данных в flutter SQL. Я хочу отобразить имя пользователя в базе данных SQL после создания таблицы, но метод получения возвращает значение null.

Я показываю такое имя пользователя в классе home

body: Center(
        child: user != null ? Text("Saved \n \n Username: '${user.username}' ")
                              : Text("Not saved"),
      ),

Здесь это код страницы входа

BuildContext _ctx;
  bool _isLoading = false;
  final _formKey = new GlobalKey<FormState>();
  final scaffoldKey = new GlobalKey<ScaffoldState>();

  String _username,_password;

  LoginPagePresenter _presenter;

  @override
  void initState(){
    _presenter = new LoginPagePresenter(this);

  }

  void _submit(){
    final form = _formKey.currentState;
    if(form.validate()){
      _isLoading = true;
      form.save();
      _presenter.doLogin(_username, _password);
    }
  }

  void _showsnackbar(String text){
    scaffoldKey.currentState.showSnackBar(new SnackBar(
      content: new Text(text),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return _isLoading ? Loading() :Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.black,
        title: Text('Login Page',textAlign: TextAlign.center,),
      ),
      body: Container(
        padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
        child: Form(
          key: _formKey,
          child: Column(
            children: <Widget>[
              SizedBox(height: 20.0),
              TextFormField(
                decoration: InputDecoration(labelText:'Username' ),
                validator: (val) => val.isEmpty ? 'Enter Username' : null,
                onChanged: (val) {
                  setState(() => _username = val);
                },
              ),
              SizedBox(height: 20.0),
              TextFormField(
                obscureText: true,
                decoration: InputDecoration(labelText:'Password' ),
                validator: (val) => val.length < 6 ? 'Enter a password 6+ chars long' : null,
                onChanged: (val) {
                  setState(() => _password = val);
                },
              ),
              SizedBox(height: 20.0),
              RaisedButton(
                color: Colors.pink[400],
                child: Text(
                  'Sign In',
                  style: TextStyle(color: Colors.white),
                ),
                onPressed: () async {
                  _submit();

                }
              ),
            ],
          ),
        ),
      ),

    );
  }

  @override
  void onLoginError(String error) {
    _showsnackbar(error);
    setState(() {
      _isLoading = false;
    });
  }

  @override
  void onLoginSuccess(User user) async {
    _showsnackbar(user.toString());
    setState(() {
      _isLoading = false;
    });
    var db = new DatabaseHelper();
    await db.saveUser(user);
    Navigator.of(_ctx).push(MaterialPageRoute<Null>(
                            builder: (BuildContext context){
                              return new Home(
                                user:user,
                              );
                            }
                        ));

  }


Вот класс пользователя

class User{

  String _username;
  String _password;

  User(this._username,this._password);

  User.map(dynamic obj){
    this._username = obj['username'];
    this._password = obj['password'];
  }



  String get username => _username;
  String get password => _password;

  Map<String,dynamic> toMap(){
    var map = new Map<String,dynamic>();
    map["username"] = _username;
    map["password"] = _password;
    return map;
  }
}

А это вспомогательный класс базы данных

class DatabaseHelper{
  static final DatabaseHelper _instance = new DatabaseHelper.internal();
  DatabaseHelper.internal();
  factory DatabaseHelper() => _instance;

  static Database _db;

  Future<Database> get db async{
    if(_db!= null)
    {
      return _db;
    }
    _db = await initdb();
    return _db;
  }

  initdb() async{
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path,"main.db");
    var ourDb = await openDatabase(path,version:1,onCreate:_onCreate);
    return ourDb;

  }

  void _onCreate(Database db,int version)async {
    await db.execute("CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT,password TEXT)");
    print("Table created");
  }
  //insertion of data
  Future<int> saveUser(User user)async {
    var dbClient = await db;
    int res = await dbClient.insert("User", user.toMap());
    return res;
  }

  // deleting data
  Future<int> deleteUser(User user)async {
    var dbClient = await db;
    int res = await dbClient.delete("User");
    return res;
  }
}

это презентатор входа

abstract class LoginPageContract{

  void onLoginSuccess(User user);
  void onLoginError(String error);

}

class LoginPagePresenter{
  LoginPageContract _view;
  RestData api = new RestData();
  LoginPagePresenter(this._view);

doLogin(String username,String password){
  api
    .login(username, password)
    .then((user)=> _view.onLoginSuccess(user))
    .catchError((onError)=>_view.onLoginError(onError()));
  }
}

Это ссылка на github для справки: https://github.com/meadows12/sql

Пожалуйста, помогите !!

1 Ответ

0 голосов
/ 09 мая 2020

Все, что вам нужно сделать, это получить доступ к объекту пользователя как «widget.user» вместо «user». Итак, следующий трюк поможет:

body: Center(
        child: widget.user != null ? Text("Saved \n \n Username: '${widget.user.username}' ")
                              : Text("Not saved"),
      )

В коде есть еще одна проблема. Вы не назначаете контекст сборки переменной _ctx. Итак, в вашем коде на гитхабе не произошло смены экрана. Я добавил одну строку в login.dart, как показано ниже, чтобы она работала:

Widget build(BuildContext context) {
    _ctx = context;
    return _isLoading ? Loading() :Scaffold(______________

Результат:

...