So I'm trying to send a value that will be added to displaycontact_list, however I would like to Create an if statement beforehand to check whether the value is a number or a string, if it is a number it will add the list based on Contact.phones.first.number and if it is a String it will add the list based on Contact.name.first
This is what I'm stuck on, I've been stuck on this for a couple of hours
class _PulsaNewScreenState extends State<PulsaNewScreen> {
_prefixImage() {
return InkWell(
child: Image.asset(
AssetsImages.redbank_kontak,
scale: 3,
),
);
}
bool isNumericUsingRegularExpression(String string) {
final numericRegex = RegExp(r'^-?(([0-9]*)|(([0-9]*)\.([0-9]*)))$');
return numericRegex.hasMatch(string);
}
bool isSearch = false;
List<Contact>? contacts;
late List<Contact> displaycontact_list = List.from(contacts!);
void updateList(String value) {
print(value);
print(isNumericUsingRegularExpression(value));
setState(() {
if (isNumericUsingRegularExpression(value) == true) {
print("its in hereee");
displaycontact_list = contacts!
.where((element) => element.phones.first!.number.contains(value))
.toList();
print("completed");
print(displaycontact_list);
} else {
print("not in there how??");
displaycontact_list = contacts!
.where((element) =>
element.name.first!.toLowerCase().contains(value.toLowerCase()))
.toList();
}
print(displaycontact_list);
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
getContact();
}
void getContact() async {
if (await FlutterContacts.requestPermission()) {
contacts = await FlutterContacts.getContacts(
withProperties: true, withPhoto: true);
print(contacts);
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: customAppBar(context, 'Pulsa'),
backgroundColor: Colors.white,
body: SafeArea(
child: Column(
children: [
NewAppBar2("Pulsa"),
Padding(
padding: EdgeInsets.symmetric(
horizontal: ResponsiveSize.width(context, 0.05),
vertical: 10,
),
child: customTextFormField(
context,
action: TextInputAction.done,
textSize: 14,
vertical: 0,
prefixIcon: _prefixImage,
hint: "Input Phone number",
change: (value) {
print(displaycontact_list);
setState(() {
isSearch = true;
});
updateList(value);
},
),
),
SizedBox(
height: 20,
),
(contacts == null)
? Center(child: CircularProgressIndicator())
: Expanded(
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: !isSearch
? contacts!.length
: displaycontact_list.length,
itemBuilder: (BuildContext context, int index) {
Uint8List? image = contacts![index].photo;
Uint8List? image2 = displaycontact_list![index].photo;
String num = (contacts![index].phones.isNotEmpty)
? (contacts![index].phones.first.number)
: "--";
String num2 =
(displaycontact_list![index].phones.isNotEmpty)
? (displaycontact_list![index]
.phones
.first
.number)
: "--";
return !isSearch
? ListTile(
leading: (contacts![index].photo == null)
? const CircleAvatar(
backgroundColor: Colors.black,
child: CircleAvatar(
child: Icon(
Icons.person,
color: ThemeColors.redbankRed,
),
backgroundColor: Colors.white,
),
)
: CircleAvatar(
backgroundImage: MemoryImage(image!),
),
title: Text(
"${contacts![index].name.first} ${contacts![index].name.last}"),
subtitle: Text(num),
onTap: () {
/* if (contacts![index].phones.isNotEmpty) {
launch('tel: ${num}');
}*/
})
: ListTile(
leading: (displaycontact_list![index].photo ==
null)
? const CircleAvatar(
backgroundColor: Colors.black,
child: CircleAvatar(
child: Icon(
Icons.person,
color: ThemeColors.redbankRed,
),
backgroundColor: Colors.white,
),
)
: CircleAvatar(
backgroundImage: MemoryImage(image2!),
),
title: Text(
"${displaycontact_list![index].name.first} ${displaycontact_list![index].name.last}"),
subtitle: Text(num2),
onTap: () {
/* if (contacts![index].phones.isNotEmpty) {
launch('tel: ${num}');
}*/
});
},
),
),
SizedBox(
height: 20,
),
],
),
));
}
}
I've tried to create an if statement after the onchanged to check whether val is numeric or not, if it is numeric it will return true and if it is not it will return false. The if statement actually goes into the if statement and prints "its in hereee" when it is a numeric and it goes outside the if statement into the else statement when it is a string however it doesnt seem that it is adding it into the List even though it is inside of the If Statement. Would love some guidance. Thanks
The current program outputs this error code
======== Exception caught by widgets ===============================================================
The following StateError was thrown while calling onChanged:
Bad state: No element
When the exception was thrown, this was the stack:
#0 List.first (dart:core-patch/growable_array.dart:343:5)
#1 _PulsaNewScreenState.updateList.<anonymous closure>.<anonymous closure> (package:Redbank/src/presentation/screens/pulsa_prabayar_screen/pulsa_new_screen.dart:46:48)
#2 WhereIterator.moveNext (dart:_internal/iterable.dart:439:13)
#3 new _GrowableList._ofOther (dart:core-patch/growable_array.dart:202:26)
#4 new _GrowableList.of (dart:core-patch/growable_array.dart:152:26)
#5 new List.of (dart:core-patch/array_patch.dart:51:28)
#6 Iterable.toList (dart:core/iterable.dart:470:12)
#7 _PulsaNewScreenState.updateList.<anonymous closure> (package:Redbank/src/presentation/screens/pulsa_prabayar_screen/pulsa_new_screen.dart:47:14)
CodePudding user response:
the problem might be because the element.phones
OR element.name
are empty, so when you try to call element.name.first
on an empty list, it will throw the given error,
so your checks should be changed to:
if (isNumericUsingRegularExpression(value) == true)
displaycontact_list = contacts!
.where((element){
if(element.phones.isEmpty) return false;
return element.phones.first!.number.contains(value);
})
.toList();
else
displaycontact_list = contacts!
.where((element){
if(element.name.isEmpty) return false;
return element.name.first!.toLowerCase().contains(value);
})
.toList();