fetchFieldOptions method
Implementation
Future<void> fetchFieldOptions(
Field field, Map<String, dynamic> formValues) async {
if (field.source == null) return;
if (optionsInProgress[field.name] == true) return;
optionsInProgress[field.name] = true;
Source source = field.source!;
String? url = source.api;
final labelKey = source.labelKey ?? 'name';
final valueKey = source.valueKey ?? 'id';
final staticOptions = source.options ?? [];
final alwaysRefresh = source.alwaysRefresh ?? false;
bool shouldFetch =
!(options.containsKey(field.name) && options[field.name]!.isNotEmpty);
bool dependenciesMissing = false;
// Handle dependencies
if (field.dependentOn != null && field.dependentOn!.isNotEmpty) {
for (final dep in field.dependentOn!) {
final val = formValues[dep];
final last = dependentValues[field.name]?[dep];
if ((val == null || val.toString().isEmpty) &&
!(url?.contains("page=") ?? false)) {
dependenciesMissing = true;
}
if (val != last) {
shouldFetch = true;
dependentValues[field.name] = {
...(dependentValues[field.name] ?? {}),
dep: val,
};
}
}
}
if (url != null) {
url = replaceUrlPlaceholders(url, formValues);
}
if (dependenciesMissing || (!shouldFetch && !alwaysRefresh)) {
optionsInProgress[field.name] = false;
notifyListeners();
return;
}
if (url != null && url.isNotEmpty) {
try {
final response = await httpClient?.get(url);
if (response?.statusCode == 200) {
final jsonData = response?.data;
final List dataList = jsonData['result'] ??
jsonData['data'] ??
jsonData['results'] ??
[];
List<Option> newOptions = dataList
.map<Option>((item) => Option(
label: item[labelKey].toString(),
value: item[valueKey],
item: item is Map<String, dynamic>
? item
: Map<String, dynamic>.from(item),
))
.toList();
setFieldOptions(field.name, newOptions);
if (field.autoFill != null) {
handleAutoFill(field);
}
} else {
throw Exception("Failed to fetch options for ${field.name}");
}
} catch (e) {
setFieldOptions(field.name, []);
}
} else if (staticOptions.isNotEmpty) {
setFieldOptions(field.name, staticOptions);
if (field.autoFill != null) {
handleAutoFill(field);
}
}
optionsInProgress[field.name] = false;
notifyListeners();
}