I have a screen that has a static form and then I add some dynamic fields that come from an API. then each field has a validator, but for the dynamic fields I did it with a FutureBuilder, then after I added the FutureBuilder the validators only work for the dynamic fields and not for the static ones
Here is my static fields:
CampoUserSenha(
textInputAction: TextInputAction.next,
readOnly: false,
validator: (val) => combine([
() => isNotEmpty(val),
() => validaNome(
val,
),
]),
controller: _nomeController,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))
],
prefixIcon: const Icon(
Icons.account_circle,
color: roxoPadrao,
),
labelText: 'Nome completo',
obscureText: false,
),
const SizedBox(
height: 20,
),
CampoUserSenha(
textInputAction: TextInputAction.next,
readOnly: false,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
controller: phoneController,
prefixIcon: const Icon(
Icons.phone,
color: roxoPadrao,
),
labelText: 'Numero de contato',
keyboardType: TextInputType.number,
obscureText: false,
),
here my FutureBuilder:
FutureBuilder<List<FormulariosModel>>(
future: FormulariosHttp().formulariosEmpresa(context),
builder: (BuildContext context,
AsyncSnapshot<List<FormulariosModel>> snapshot) {
if (snapshot.hasData) {
List<FormulariosModel> formularios = snapshot.data!;
List<Widget> campos = [];
Map<String, Widget Function(BuildContext, FormulariosModel)>
fieldTypeMap = {
'5': checkBox,
'T': (context, formulario) {
if (formulario.formatacao == '4') {
return campoData(context, formulario);
} else if (formulario.originalFormat == 'S') {
return campoMascaraDinamica(context, formulario);
} else if (formulario.formatacao == '5') {
return campoDataHora(context, formulario);
} else if (formulario.originalFormat == '6') {
return campoHora(context, formulario);
} else if (formulario.formatacao == '9') {
return campoIp(context, formulario);
} else if (formulario.formatacao == 'M') {
return campoMoeda(context, formulario);
} else if (formulario.formatacao == 'I') {
return campoNumeroInteiro(context, formulario);
} else if (formulario.formatacao == null) {
return campoTextoPuro(context, formulario);
}
return campoCpf(context, formulario);
},
'S': campoLista,
'R': campoRadio,
'6': campoMultiplaSelecoes,
'L': campoAreaDeTexto,
// Adicione mais mapeamentos aqui conforme necessário
};
for (FormulariosModel formulario in formularios) {
if (fieldTypeMap.containsKey(formulario.type)) {
campos.add(fieldTypeMap[formulario.type]!(
context, formulario));
}
}
return Column(
children: campos.map((campo) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: campo,
);
}).toList(),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
And my method that I call to create an account:
criarConta([FormulariosModel? formulario]) async {
final nome = _nomeController.text;
final telefone = phoneController.text;
final email = _emailController.text;
final senha = passwordController.text;
final confirmaSenha = passwordConfirmController.text;
String cpf = _cpfController.text;
bool formIsValid = formKey.currentState!.validate();
if (formulario?.requireed == true && !isChecked) {
FlushBarComponente.mostrar(context, 'Preencha os campos obrigatórios',
Icons.warning_amber, vermelhoPadrao);
return;
}
if (formIsValid && _validaCPF(context, cpf) &&
_validaNomeEmail(context, nome, email, senha, confirmaSenha) == true) {
var resposta = await CriarContaHttp()
.criarConta(nome, telefone, email, senha, context);
if (resposta != null) {
if (resposta.requireValidation == true) {
Future.delayed(const Duration(milliseconds: 100), () {
Navigator.pushNamed(context, Routes.validaEmail);
});
} else if (resposta.wait == true) {
Future.delayed(const Duration(milliseconds: 100), () {
Navigator.pushNamed(context, Routes.waitScreen);
});
} else if (resposta.error == true) {
FlushBarComponente.mostrar(
context, resposta.message, Icons.warning_amber, vermelhoPadrao);
}
} else {
FlushBarComponente.mostrar(context, 'Erro ao criar conta',
Icons.warning_amber, vermelhoPadrao);
}
}
}
obs: I debugged it and it is not arriving in the validator, and when I removed the FutureBuilder it returned the noraml message which is the one that appears below the field in red
I don't know if this is what's causing your problem but I notice one mistake. In your
FutureBuilderyou haveBut this makes it that it calls the future again on every rebuild. What you'd want to do have something like this in the state
and then use
in the
FutureBuilder