How to retrieve a TextEditingController inside a Controller layer with Getx?

Issue

I have this statement in my View layer

TextEditingController controllerDestino = TextEditingController();

And I want to recover this controllerDestino, to use within a method that is in my Controller layer.

 statusUberNaoChamado() {
showBoxAdress = true;

changeMainButton("Chamar", Color(0xFF1ebbd8), () {
  callUber("I need pass the controller here");
});

update();}

Thank you in advance for your attention 🙂

Solution

Define/instantiate the TextEditingController as a field inside your GetxController you’re using to control your form / implement business logic.

class DestinoFormControllerX extends GetxController {
  static DestinoFormControllerX get i => Get.find();
  final GlobalKey<FormBuilderState> key = GlobalKey<FormBuilderState>();

  // ↓ place the text editing controller inside your... controller :)
  var controllerDestino = TextEditingController();

And use the TextEditingController values wherever you need in your GetxController

  void resetForm() {
    key.currentState.reset();
    controllerDestino.text = '';
    focusNode.requestFocus();
  }

In your View layer, inject your GetxController, and get the text editing controller & access any other methods/fields you need.

class DestinoForm extends StatelessWidget {
  final void Function() submitHandler;

  DestinoForm({this.submitHandler});

  @override
  Widget build(BuildContext context) {
    final dcx = Get.put(DestinoFormControllerX());
    // ↑ inject GetxController, be careful to put *inside* build method

    return FormBuilder(
      key: dcx.key,
      child: Column(
        children: [
          FormBuilderTextField(
            name: 'destino',
            controller: dcx.controllerDestino,
            decoration: InputDecoration(
              labelText: 'Destino',
            ),

Most forms would have Reset & Submit buttons. There you can call methods on your GetxController….

      actions: [
        FlatButton(
          child: Text('Reset'),
          onPressed: () => DestinoFormControllerX.i.resetForm(),
        ),

Side Note

If you’re instantiating / injecting your GetxController in your Form Widget with Get.put(), do so inside the build method of your Form Widget.

Otherwise, you’ll likely have TextEditingControllers calling setState on a StatefulWidget (the textfield) that is no longer mounted in the widget tree:

════════ Exception caught by foundation library ════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for TextEditingController:
setState() called after dispose(): _FormBuilderTextFieldState#96390(lifecycle state: defunct, not mounted)

Good

class DestinoForm extends StatelessWidget {
  final void Function() submitHandler;

  DestinoForm({this.submitHandler});

  @override
  Widget build(BuildContext context) {
    final dcx = Get.put(DestinoFormControllerX());
    // ↑ inject GetxController, be careful to put *inside* build method

Bad

class DestinoForm extends StatelessWidget {
  final void Function() submitHandler;
  final dcx = Get.put(DestinoFormControllerX());
  // ↑ wrong place, DestinoFormControllerX gets linked to previous route

  DestinoForm({this.submitHandler});

  @override
  Widget build(BuildContext context) {

More detail on Github, mentioning proper injection / usage of GetX.

Answered By – Baker

Answer Checked By – Mildred Charles (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.