skip to Main Content

I have a list of accounts that I have stored in Firestore, and when I want to edit the accounts, I want to be able to have the current information already pre-filled with what is there. I’m able to grab the correct info, and can print to console that the information is there, but the fields will not pre-fill with the information. Any help would be appreciated!

Here is part of the code for my editscreen form:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import './nav_bar.dart';

class EditSettings extends StatefulWidget {
  const EditSettings({
    super.key,
  });
  static const routeName = '/edit-settings';

  @override
  State<EditSettings> createState() => _EditSettingsState();
}

class _EditSettingsState extends State<EditSettings> {
  final _form = GlobalKey<FormState>();

  void homeRoute(BuildContext ctx) {
    Navigator.of(ctx).pushReplacementNamed(NavBar.routeName);
  }

  final _urlFocusNode = FocusNode();
  final _usernameFocusNode = FocusNode();
  final _passwordFocusNode = FocusNode();
  //final _confirmPassFocusNode = FocusNode();


  var _initValues = {
    'siteName': '',
    'siteUrl': '',
    'userName': '',
    'password': '',
  };

  @override
  void dispose() {
    _urlFocusNode.dispose();
    _usernameFocusNode.dispose();
    _passwordFocusNode.dispose();
    //_confirmPassFocusNode.dispose();
    super.dispose();
  }

  var _isInit = true;

  bool _passwordVisible = false;

  @override
  void initState() {
    _passwordVisible = false;
    super.initState();
  }

  @override
  void didChangeDependencies() async {
    if (_isInit) {
      if (ModalRoute.of(context)!.settings.arguments != null) {
        final accountId = ModalRoute.of(context)!.settings.arguments as String;
        if (accountId.isNotEmpty) {
          final _editedAccount = await FirebaseFirestore.instance.collection('accounts').doc(accountId).get();
          print(Text(_editedAccount.data().toString()));
          _initValues = {
            'siteName': _editedAccount['siteName'],
            'siteUrl': _editedAccount['url'],
            'userName': _editedAccount['username'],
            'password': _editedAccount['password'],
          };
        }
      }
      _isInit = false;
    }
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Edit Settings')),
      body: Padding(
        padding: const EdgeInsets.only(
          top: 40,
          left: 10,
          right: 10,
        ),
        child: Form(
          key: _form,
          child: ListView(
            children: <Widget>[
              TextFormField(
                initialValue: _initValues['siteName'],    <---- This part does not work
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Name of Site',
                  hintText: 'Site Name',
                ),```


I have changed the async method, attempted to grab the instance outside of didChangeDependencies but I may have implemented that incorrectly. Any assistance would be appreciated!

2

Answers


  1. Chosen as BEST ANSWER

    Ok, figured it out! I had to use a future builder, return the data and pass in the return value. Here's the code for anyone looking for something similar!

    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:flutter/material.dart';
    import './nav_bar.dart';
    
    class EditSettings extends StatefulWidget {
      const EditSettings({
        super.key,
      });
      static const routeName = '/edit-settings';
    
      @override
      State<EditSettings> createState() => _EditSettingsState();
    }
    
    class _EditSettingsState extends State<EditSettings> {
      final _form = GlobalKey<FormState>();
    
      void homeRoute(BuildContext ctx) {
        Navigator.of(ctx).pushReplacementNamed(NavBar.routeName);
      }
    
      final _urlFocusNode = FocusNode();
      final _usernameFocusNode = FocusNode();
      final _passwordFocusNode = FocusNode();
      //final _confirmPassFocusNode = FocusNode();
    
      @override
      void dispose() {
        _urlFocusNode.dispose();
        _usernameFocusNode.dispose();
        _passwordFocusNode.dispose();
        //_confirmPassFocusNode.dispose();
        super.dispose();
      }
    
      bool _passwordVisible = false;
    
      @override
      void initState() {
        _passwordVisible = false;
        super.initState();
      }
    
      Future<DocumentSnapshot> getData() async {
        final accountId = ModalRoute.of(context)!.settings.arguments as String;
    
        return await FirebaseFirestore.instance
            .collection('accounts')
            .doc(accountId)
            .get();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Edit Settings')),
          body: Padding(
            padding: const EdgeInsets.only(
              top: 40,
              left: 10,
              right: 10,
            ),
            child: FutureBuilder(
              future: getData(),
              builder: (context, querySnapshot) {
                if (querySnapshot.connectionState == ConnectionState.waiting) {
                  return const Center(
                    child: CircularProgressIndicator(),
                  );
                }
                return Form(
                  key: _form,
                  child: ListView(
                    children: <Widget>[
                      TextFormField(
                        initialValue: querySnapshot.data!['siteName'],
                        decoration: const InputDecoration(
                          border: OutlineInputBorder(),
                          labelText: 'Name of Site',
                          hintText: 'Site Name',
                        ),
    

  2. You need to use setState after getting the initial value to update the UI state.

        @override
      void didChangeDependencies() async {
        if (_isInit) {
          if (ModalRoute.of(context)!.settings.arguments != null) {
            final accountId = ModalRoute.of(context)!.settings.arguments as String;
            if (accountId.isNotEmpty) {
              final _editedAccount = await FirebaseFirestore.instance.collection('accounts').doc(accountId).get();
              print(Text(_editedAccount.data().toString()));
           ///add setSetate here
           setState({
            initValues = {
                'siteName': _editedAccount['siteName'],
                'siteUrl': _editedAccount['url'],
                'userName': _editedAccount['username'],
                'password': _editedAccount['password'],
              };
            })
              _
            }
          }
          _isInit = false;
        }
        super.didChangeDependencies();
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search