Created
August 21, 2023 18:29
-
-
Save justinmc/b8c96286ae3d35c47c202123197ff6a0 to your computer and use it in GitHub Desktop.
An example of async form validation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Async Validator Example', | |
debugShowCheckedModeBanner: false, | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: const _MyHomePage(title: 'Async Validator Example'), | |
); | |
} | |
} | |
class _MyHomePage extends StatefulWidget { | |
const _MyHomePage({required this.title}); | |
final String title; | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<_MyHomePage> { | |
final TextEditingController _controller = TextEditingController(); | |
String? _valueCheckedForCollision; | |
bool? _hasCollision; | |
String? _validator(String? value) { | |
if (_controller.value.text == '') { | |
return 'Can\'t be empty!'; | |
} | |
if (_controller.value.text != _valueCheckedForCollision) { | |
_checkForCollision(); | |
return 'Checking for collision...'; | |
} | |
return _hasCollision ?? false ? 'This already exists :(' : null; | |
} | |
// Check if the current value in the field is a collision, and update state with result. | |
void _checkForCollision() async { | |
final String valueCheckedForCollision = _controller.value.text; | |
final bool hasCollision = await _fakeCollisionAPICall(valueCheckedForCollision); | |
if (valueCheckedForCollision != _controller.value.text) { | |
return; | |
} | |
setState(() { | |
_valueCheckedForCollision = valueCheckedForCollision; | |
_hasCollision = hasCollision; | |
}); | |
} | |
// Returns a future that resolves to false iff there is no collision on value. | |
// Hardcoded to always return an error except for the value 'asdf', for demonstration. | |
Future<bool> _fakeCollisionAPICall(String value) { | |
return Future.delayed(const Duration(seconds: 4), () => value != 'asdf'); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
TextFormField( | |
controller: _controller, | |
autovalidateMode: AutovalidateMode.always, | |
validator: _validator, | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment