Получить значение из функции, возвращающей будущее внутри виджета - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь проверить, существует ли имя пользователя в моей базе данных, когда пользователи регистрируются. Поэтому я сделал функцию для проверки базы данных и хотел, чтобы она возвращала логическое значение, но так как вызов базы данных возвращает будущее, я превратил функцию в асинхронную c функцию, чтобы я мог ждать ответа. Поскольку все функции asyn c возвращают будущее, у меня теперь есть будущее вместо логического. Я хочу иметь возможность вызывать мою функцию несколько раз в моей функции сборки, но вместо логического значения я получаю будущее, и если я пытаюсь добавить ожидание, я должен сделать это asyn c, что означает, что мне нужно будет вернуть будущее не виджет.

Вот виджет. _account.isUsernameAvailable(value) - это функция, которую я хочу вернуть, а ниже - моя функция сборки. Из других ответов, которые я читал, сборка future, похоже, является популярным вариантом, но из того, что я вижу, будущая ценность должна быть известна заранее. В моем случае это невозможно. Любой совет или помощь будет принята с благодарностью.

  final _account = Account();

  @override
  Widget build(BuildContext context) {
    return loading ? Loading() : Scaffold(
      appBar: AppBar(
        title: Text('Sign Up'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Form(
              key: _formKey,
              child: Column(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 10.0),
                    child: TextFormField(
                      onSaved: (value) {
                        _username = value.trim();
                      },
                      validator: (value) {
                        if (value.isEmpty) {
                          return 'Please enter a username';
                        } else if (_account.isUsernameAvailable(value)) {
                          return 'Username already exists';
                        }
                        return null;
                      },
                      decoration: InputDecoration(
                        hintText: 'Username',
                      ),
                    ),
                  ),

Вот код класса учетной записи.

  Future isUsernameAvailable(String username) async {
    QuerySnapshot docs = await userCollection
        .where('username', isEqualTo: username)
        .getDocuments();
    return docs.documents.isEmpty;
  }

ОБНОВЛЕНИЕ:

Как я и предлагал, я пытался использовать оператор then в функции.

  bool _userExist = false;
  checkUserValue<bool>(String user) {
    _account
        .isUsernameAvailable(user).then((val){
          print(val);
      if(val){
        print ("UserName Already Exits");
        _userExist = val;
      }
      else{
        print ("UserName is Available");
        _userExist = val;
      }
    });
    print('here');
    return _userExist;
  }

и мой виджет теперь выглядит следующим образом.

    child: TextFormField(
       onSaved: (value) {
          _username = value.trim();
       },
       validator: (value) {
          return checkUserValue(value) ? "Username taken" : null;
       },

Кажется, он работает, но мне нужно дважды проверить его, чтобы он работал. Я думаю, что значение для _userExists может быть установлено после того, как функция каким-то образом вернется, но я не совсем уверен, почему происходит такое поведение. При этом у меня есть вопрос, почему функция не возвращается до завершения .then ()?

...