Home > front end >  I can't use a disposed TextEditingController when pushed to another screen and popped, is my un
I can't use a disposed TextEditingController when pushed to another screen and popped, is my un

Time:01-19

I have a screen to create a post. There is a TextFormField there and I added dispose to its TextEditingController. However, I get an error:

════════ Exception caught by widgets library ═══════════════════════════════════
A TextEditingController was used after being disposed.
════════════════════════════════════════════════════════════════════════════════

If my understanding is correct, I think it's saying that I can't use the disposed TextEditingController when I'm pushed to another screen and popped. Hope you guys can tell me if my understanding is correct.

I referred this answer but it didn't solve my problem.

My code:

TextEditingController messageController = TextEditingController();

class CreatePostScreen extends ConsumerStatefulWidget {
  const CreatePostScreen({super.key});

  @override
  ConsumerState<CreatePostScreen> createState() => _CreatePostScreenState();
}

class _CreatePostScreenState extends ConsumerState<CreatePostScreen> with AutomaticKeepAliveClientMixin {
  @override
  void dispose() {
    messageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    …

    return Scaffold(
      appBar: AppBar(
        …
        title: Text("Create post"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Column(
          children: [
            …
            TextFormField(
              controller: enquiryMessageController,
              style: const TextStyle(color: Colors.black),
              decoration: InputDecoration(
                border: InputBorder.none,
                hintText: "What do you wish to enquire?",
                hintStyle: const TextStyle(color: Colors.black),
              ),
              keyboardType: TextInputType.text,
              textInputAction: TextInputAction.done,
            ),
          ],
        ),
      ),
    );
  }
}

messageController is outside ConsumerStatefulWidget, because the code is to make the text in TextFormField not disappear, please refer to this answer.

Feel free to leave a comment if you need more information.

I can't use a disposed TextEditingController when pushed to another screen and popped, is my understanding correct? I would appreciate any help. Thank you in advance!

CodePudding user response:

You can try defining the controller this way:

class CreatePostScreen extends ConsumerStatefulWidget {
  const CreatePostScreen({super.key});

  @override
  ConsumerState<CreatePostScreen> createState() => _CreatePostScreenState();
}

class _CreatePostScreenState extends ConsumerState<CreatePostScreen> with AutomaticKeepAliveClientMixin {
late TextEditingController messageController;


  @override
  void initState() {
    messageController = TextEditingController();
    super.initState();
  }


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

  @override
  Widget build(BuildContext context) {
    super.build(context);

    …

    return Scaffold(
      appBar: AppBar(
        …
        title: Text("Create post"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Column(
          children: [
            …
            TextFormField(
              controller: enquiryMessageController,
              style: const TextStyle(color: Colors.black),
              decoration: InputDecoration(
                border: InputBorder.none,
                hintText: "What do you wish to enquire?",
                hintStyle: const TextStyle(color: Colors.black),
              ),
              keyboardType: TextInputType.text,
              textInputAction: TextInputAction.done,
            ),
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

As I see you are declaring it as a global variable. When the screen is popped (removed from widget tree), dispose is executed. So your global TextEditingController is disposed. It is a very bad practice. You need to define it inside _CreatePostScreenState class. So whenever the screen widget initiated, a new controller widget will also be created. I hope, this solves your problem. If not, then please edit the question, add error messages, and code lines which you find from error log.

  • Related