How can I use Pinput validator with a http request?

259 views Asked by At

I`m building a code and I would like to validate the input using the Pinput widget, and I noticed that the method validator receives a String? function.

I`m making a http request to validate if the input is correct or not, but as I can`t put async on validator, how can I get my http answer to validate it ?

here`s a sample of my code :

class PinInputScreen extends StatelessWidget {
  final GlobalKey<FormFieldState<String>> _pinPutKey = GlobalKey<FormFieldState<String>>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pin Input'),
      ),
      body: Center(
        child: PinPut(
          fieldsCount: 6,
          onSubmit: (String pin) => _showSnackBar(pin),
          focusNode: FocusNode(),
          controller: TextEditingController(),
          validator:(value) {  //Can't put async here
                String? result = await myFutureMethod(); //can`t use await here
                return result;
              }
          submittedFieldDecoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(5.0),
            boxShadow: const [
              BoxShadow(
                color: Colors.black26,
                blurRadius: 2.0,
                offset: Offset(0.0, 0.0),
              )
            ],
          ),
        ),
      ),
    );
  }

  void _showSnackBar(String pin) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text('PIN : $pin'),
      duration: Duration(seconds: 2),
    ));
  }

  Future<String?> myFutureMethod() async {
    final jsonPinValidation = jsonEncode({"phone": "111111", "verificationCode": 1111});
    final response = await http.post(
        Uri.parse("https://mydomain.dev/validation"),
        body: jsonPinValidation,
        headers: {'Content-Type': 'application/json'});
    if (response.statusCode == 200) {
      return null;
    } else {
      return "Wrong Token";
    }
  }
}

I tried to use .then() function but also didn`t work .. not sure what exactly to do.

this is what I kinda needed: Code exemple of what I wanted to do

1

There are 1 answers

0
Yousef Aburayyan On

I have faced the same problem. I did intensive searching but found no way to call an async function in the validator.

So I did a workaround by clearing the inputs and re-submitting them again.

class PinInputScreen extends StatelessWidget {
  final GlobalKey<FormFieldState<String>> _pinPutKey = GlobalKey<FormFieldState<String>>();
  late bool isSMSValid = true;
  late String errorMessage = "";
  late bool isValidating = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pin Input'),
      ),
      body: Center(
        child: PinPut(
          fieldsCount: 6,
          onSubmit: (String pin) => _showSnackBar(pin),
          focusNode: FocusNode(),
          controller: TextEditingController(),
          validator: (value) {
            if (isSMSValid) {
              return null;
            }
            isSMSValid = true;
            return errorMessage;
          },
          onComplete: (value) {
            validateSMSCode();
          },
          submittedFieldDecoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(5.0),
            boxShadow: const [
              BoxShadow(
                color: Colors.black26,
                blurRadius: 2.0,
                offset: Offset(0.0, 0.0),
              )
            ],
          ),
        ),
      ),
    );
  }

  void _showSnackBar(String pin) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text('PIN : $pin'),
      duration: Duration(seconds: 2),
    ));
  }

  void validateSMSCode(String value) {
    if (isValidating) {
      isValidating = false;
      return;
    }

    isValidating = true;

    final jsonPinValidation = jsonEncode({"phone": "111111", "verificationCode": 1111});
    http.post(
        Uri.parse("https://mydomain.dev/validation"),
        body: jsonPinValidation,
        headers: {'Content-Type': 'application/json'},
    ).then((response) {
      isSMSValid = response.status;
      errorMessage = response.message;
      _refreshPinput(value);
    });
  }

  void _refreshPinput(String value) {
    _pinController.clear();
    _pinController.setText(value);
  }
}