Home > Back-end >  TextEditingController not passing text into named parameters
TextEditingController not passing text into named parameters

Time:02-12

I am really struggling to understand why my code isn't working. I'm trying to pass the text from two controllers into another widget with named parameters which writes to Firebase.

My "Test" button properly prints both _titleController.text and _descriptionController.text

TextButton(
                    onPressed: (){
                      print(_titleController.text); //works fine
                      print(_descriptionController.text); //works fine
                    },
                    child: Text('test')
                ),

However when I pass these into my next widget it's blank! If I hardcore strings into these parameters it works properly:

PushNewE3 (
                 changeTitle: _titleController.text, //does not work (empty)
                 changeDescription: _descriptionController.text, //does not work (empty)
                )

Full code:

class CreateE3 extends StatefulWidget {
  const CreateE3({Key? key}) : super(key: key);

  @override
  _CreateE3State createState() => _CreateE3State();
}

class _CreateE3State extends State<CreateE3> {
  final _titleController = TextEditingController();
  final _descriptionController = TextEditingController();


  @override
  void initState(){
    super.initState();
    _titleController.addListener(_printLatestValue);
  }

  @override
  void dispose(){
    _titleController.dispose();
    super.dispose();
  }

  void _printLatestValue(){
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('So Frustrating'),
      ),

      body: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            width: 800,
            child: Column(
              children: [
                Text('Originator: **Add Current User**')      ,
                TextField(
                  maxLength: 40,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Change Title'
                  ),
                  controller: _titleController,
                  onEditingComplete: (){
                    //_title = _titleController.text;
                  },
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(0,10,0,0),
                  child: TextFormField(
                    maxLines: 5,
                    decoration: InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'Detailed Description'
                    ),
                    controller: _descriptionController,
                  ),
                ),
                TextButton(
                    onPressed: (){
                      print(_titleController.text); //successfully prints
                      print(_descriptionController.text); //successfully prints

                    },
                    child: Text('test')
                ),
                PushNewE3 (
                 changeTitle: _titleController.text, //DOES NOT WORK (empty)
                 changeDescription: _descriptionController.text, //DOES NOT WORK (empty)
                ) 

              ],
            ),
          ),
        ],
      ),

    );
  }
}



class PushNewE3 extends StatelessWidget {
  final String changeTitle;
  final String changeDescription;

  PushNewE3({
    required this.changeTitle,
    required this.changeDescription
  });

  @override
  Widget build(BuildContext context) {
    // Create a CollectionReference called users that references the firestore collection
    CollectionReference notificationsE3 = FirebaseFirestore.instance.collection('notificationsE3');

    Future<void> pushNewE3() {
      // Call the notifications CollectionReference to add a new E3 notification
      return notificationsE3
          .add({
        //'originator': FirebaseAuth.instance.currentUser,
        'changeTitle': changeTitle,
        'changeDescription': changeDescription,
      })
          .then((value) => print("E3 Created"))
          .catchError((error) => print("Failed to create E3: $error"));
    }

    return TextButton(
      onPressed: (){
        print('start:');
        print(changeTitle);
        print(changeDescription);
        print('-end');

      },
      child: Text(
        "Create E3",
      ),
    );
  }
}

EDIT: I still don't understand why the above code doesn't work. I refactored my code into a single widget and now it's working. If anyone can explain why I would still appreciate understanding as there is clearly a gap in my knowledge.

If anyone in the future runs into the same problem here is the refactored code:

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

import 'main.dart';

var global = 'blank';

class CreateE3 extends StatefulWidget {
  const CreateE3({Key? key}) : super(key: key);

  @override
  _CreateE3State createState() => _CreateE3State();
}

class _CreateE3State extends State<CreateE3> {
  final _titleController = TextEditingController();
  final _descriptionController = TextEditingController();


  @override
  Widget build(BuildContext context) {
    // Create a CollectionReference called users that references the firestore collection
    CollectionReference notificationsE3 = FirebaseFirestore.instance.collection('notificationsE3');

    Future<void> pushNewE3() {
      // Call the notifications CollectionReference to add a new E3 notification
      return notificationsE3
          .add({
        //'originator': FirebaseAuth.instance.currentUser,
        'changeTitle': _titleController.text,
        'changeDescription': _descriptionController.text,
      })
          .then((value) => print("E3 Created"))
          .catchError((error) => print("Failed to create E3: $error"));
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(_titleController.text),
      ),

      body: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            width: 800,
            child: Column(
              children: [
                Text('Originator: **Add Current User**')      ,
                TextField(
                  maxLength: 40,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Change Title'
                  ),
                  controller: _titleController,
                  onChanged: (text){
                    setState(() {

                    });
                  },

                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(0,10,0,0),
                  child: TextFormField(
                    maxLines: 5,
                    decoration: InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'Detailed Description'
                    ),
                    controller: _descriptionController,
                  ),
                ),
                TextButton(
                    onPressed: (){
                      pushNewE3();
                    },
                    child: Text('SAVE')
                ),

              ],
            ),
          ),
        ],
      ),

    );
  }
}

CodePudding user response:

in the onPressed To pass a value and show it, you have to use setState(() { _myState = newValue; });

Something like this

TextButton(
                onPressed: (){
                  print(_titleController.text);
                  print(_descriptionController.text);
                  setState(() { _myNewText = _titleController.text; });

                },
                child: Text('test')
            ),

CodePudding user response:

I'm not sure what are you trying to do exactly but here's what I did: 1 - add a local variable _title 2 - add this code to the onPressed function:

setState(() { 
             _title= _titleController.text; 
            });

This is the whole code :

  class CreateE3 extends StatefulWidget {
     const CreateE3({Key? key}) : super(key: key);
     @override
    _CreateE3State createState() => _CreateE3State();
  }

  class _CreateE3State extends State<CreateE3> {
    final _titleController = TextEditingController();
    final _descriptionController = TextEditingController();
    String _title = 'So Frustrating';


   @override
    void initState(){
    super.initState();
   }

  @override
   void dispose(){
   _titleController.dispose();
   super.dispose();
  }


 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text(_title),
     ),

    body: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Container(
          width: 400,
          child: Column(
            children: [
              Text('Originator: **Add Current User**')      ,
              TextField(
                maxLength: 40,
                decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Change Title'
                ),
                controller: _titleController,
                onEditingComplete: (){
                  //_title = _titleController.text;
                },
              ),
              Padding(
                padding: const EdgeInsets.fromLTRB(0,10,0,0),
                child: TextFormField(
                  maxLines: 5,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Detailed Description'
                  ),
                  controller: _descriptionController,
                ),
            ),
              TextButton(
                  onPressed: (){
                    print(_titleController.text);
                    print(_descriptionController.text);
                    setState(() {
                      _title = _titleController.text;
                    });

                  },
                  child: Text('test')
              ),
            ],
          ),
        ),
        ],
      ),

    );
   }
 }

......................... so this is when you first start the app :

enter image description here

after changing the TextField and pressing the 'test button the title in the appbar change :

enter image description here

  • Related