Still on the AlertDialog validation example I recently posted, I ran into another odd problem. I fixed the validation code as per the below and it works!
import "package:flutter/material.dart";
import "package:easy_wallet/resources/constants.dart";
class WalletApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(title: "EasyWallet", home: EasyWalletHomePage());
}
}
class EasyWalletHomePage extends StatefulWidget {
@override
_EasyWalletState createState() => _EasyWalletState();
}
class _EasyWalletState extends State<EasyWalletHomePage> {
final TextEditingController _nameController = TextEditingController();
@override
void initState() {
super.initState();
}
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print("BUILD1!");
return Scaffold(
body: Center(
child: Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 15,
children: [
Text("No wallets yet..."),
ElevatedButton(
key: KEY_ADD_WALLET,
child: const Text("➕"),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
),
onPressed: () {
_showAddWalletDialog(context);
})
],
),
),
);
}
Future<void> _showAddWalletDialog(BuildContext context) async {
print("BUILD2!");
return await showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: const Text('Add wallet'),
content: Wrap(
children: [
Text("Insert wallet name:"),
TextField(
controller: _nameController,
maxLength: 40,
onChanged: (value) {
setState(() {});
},
decoration: InputDecoration(
hintText: "eg: home"
),
),
],
),
actions: <Widget>[
TextButton(
child: const Text('CANCEL'),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
),
TextButton(
child: const Text('OK'),
onPressed: (!_isValidName()) ? null : () {
Navigator.pop(context);
},
)
],
);
}
);
});
}
bool _isValidName() {
return _nameController.value.text.isNotEmpty;
}
}
void main() {
runApp(WalletApp());
}
I want now to go back developing in TDD and started I wrote the test:
testWidgets('show add wallet dialog', (WidgetTester tester) async {
await tester.pumpWidget(WalletApp());
expect(find.byType(Dialog), findsNothing);
var button = find.byKey(KEY_ADD_WALLET);
await tester.tap(button);
await tester.pumpAndSettle();
expect(find.byType(Dialog), findsOneWidget);
});
however, when I run it, I get the error:
The following assertion was thrown while finalizing the widget tree: A TextEditingController was used after being disposed. Once you have called dispose() on a TextEditingController, it can no longer be used.
When the exception was thrown, this was the stack: #0 ChangeNotifier._debugAssertNotDisposed. (package:flutter/src/foundation/change_notifier.dart:114:9) #1 ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:120:6)
following, a long stack trace.
If I remove _nameController.dispose(); the the test runs...
What am I doing wrong?