Reputation: 309
I'm trying to display a scaffold msg when user inputted a value greater than some other value...
It is working fine until I clear the input...
After clearing the input it throws an exception...
Here it is...
══╡ EXCEPTION CAUGHT BY WIDGETS ╞═══════════════════════════════════════════════════════════════════
The following FormatException was thrown while calling onChanged:
Invalid number (at character 1)
^
When the exception was thrown, this was the stack:
#0 int._handleFormatError (dart:core-patch/integers_patch.dart:129:7)
#1 int.parse (dart:core-patch/integers_patch.dart:55:14)
#2 _GeneralTabState.build.<anonymous closure>.<anonymous closure>
(package:shop_app_vendor/screens/add_products/general_tab.dart:247:25)
#3 new TextFormField.<anonymous closure>.onChangedHandler (package:flutter/src/material/text_form_field.dart:188:25)
#4 EditableTextState._formatAndSetValue (package:flutter/src/widgets/editable_text.dart:2630:27)
#5 EditableTextState.userUpdateTextEditingValue (package:flutter/src/widgets/editable_text.dart:2919:5)
#6 EditableTextState._replaceText (package:flutter/src/widgets/editable_text.dart:3144:5)
#7 CallbackAction.invoke (package:flutter/src/widgets/actions.dart:534:39)
#8 ActionDispatcher.invokeAction (package:flutter/src/widgets/actions.dart:573:21)
#9 Actions.invoke.<anonymous closure> (package:flutter/src/widgets/actions.dart:872:48)
#10 Actions._visitActionsAncestors (package:flutter/src/widgets/actions.dart:653:18)
#11 Actions.invoke (package:flutter/src/widgets/actions.dart:866:30)
#12 _DeleteTextAction.invoke (package:flutter/src/widgets/editable_text.dart:4042:20)
#13 _OverridableContextAction.invokeDefaultAction (package:flutter/src/widgets/actions.dart:1696:28)
#14 _OverridableActionMixin.invoke (package:flutter/src/widgets/actions.dart:1559:9)
#15 ActionDispatcher.invokeAction (package:flutter/src/widgets/actions.dart:571:21)
#16 ShortcutManager.handleKeypress (package:flutter/src/widgets/shortcuts.dart:755:38)
#17 _ShortcutsState._handleOnKey (package:flutter/src/widgets/shortcuts.dart:956:20)
#18 FocusManager._handleKeyMessage (package:flutter/src/widgets/focus_manager.dart:1687:32)
#19 KeyEventManager._dispatchKeyMessage (package:flutter/src/services/hardware_keyboard.dart:828:34)
#20 KeyEventManager.handleRawKeyMessage (package:flutter/src/services/hardware_keyboard.dart:875:15)
#21 BasicMessageChannel.setMessageHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:77:49)
#22 BasicMessageChannel.setMessageHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:76:47)
#23 _DefaultBinaryMessenger.setMessageHandler.<anonymous closure> (package:flutter/src/services/binding.dart:380:35)
#24 _DefaultBinaryMessenger.setMessageHandler.<anonymous closure> (package:flutter/src/services/binding.dart:377:46)
#25 _invoke2.<anonymous closure> (dart:ui/hooks.dart:190:15)
#29 _invoke2 (dart:ui/hooks.dart:189:10)
#30 _ChannelCallbackRecord.invoke (dart:ui/channel_buffers.dart:42:5)
#31 _Channel.push (dart:ui/channel_buffers.dart:132:31)
#32 ChannelBuffers.push (dart:ui/channel_buffers.dart:329:17)
#33 PlatformDispatcher._dispatchPlatformMessage (dart:ui/platform_dispatcher.dart:589:22)
#34 _dispatchPlatformMessage (dart:ui/hooks.dart:89:31)
(elided 3 frames from dart:async)
════════════════════════════════════════════════════════════════════════════════════════════════════
And here's my code...
scf.dart
class SCF {
scaffoldMsg({context, msg}) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(msg),
backgroundColor: Colors.red,
action: SnackBarAction(
label: 'OK',
textColor: Colors.white,
onPressed: () {
ScaffoldMessenger.of(context).clearSnackBars();
},
),
));
}
}
general_tab.dart
class GeneralTab extends StatefulWidget {
const GeneralTab({Key? key}) : super(key: key);
@override
State<GeneralTab> createState() => _GeneralTabState();
}
class _GeneralTabState extends State<GeneralTab> {
final SCF _scf = SCF();
@override
Widget build(BuildContext context) {
return Consumer<ProductProvider>(
builder: (context, provider, child) {
return ListView(
padding: const EdgeInsets.all(15.0),
children: [
// Regular Price
FormFieldInput(
label: 'Regular Price',
inputType: TextInputType.number,
onChanged: (value) {
provider.getFormData(regularPrice: int.parse(value));
},
),
// Sales Price
FormFieldInput(
label: 'Sales Price',
inputType: TextInputType.number,
onChanged: (value) {
if (int.parse(value) > provider.productData!['regularPrice']) {
_scf.scaffoldMsg(
context: context,
msg: 'Sales price should be less than regular price',
);
}
setState(() {
provider.getFormData(salesPrice: int.parse(value));
});
},
),
],
);
},
);
}
}
product_provider.dart
class ProductProvider with ChangeNotifier {
Map<String, dynamic>? productData = {};
getFormData({
int? regularPrice,
int? salesPrice,
}) {
if (regularPrice != null) {
productData!['regularPrice'] = regularPrice;
}
if (salesPrice != null) {
productData!['salesPrice'] = salesPrice;
}
notifyListeners();
}
}
form_field.dart
class FormFieldInput extends StatelessWidget {
final String? label;
final void Function(String)? onChanged;
final TextInputType? inputType;
const FormFieldInput({
Key? key,
this.label,
this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: InputDecoration(
label: Text(label!),
),
onChanged: onChanged,
);
}
}
This is working fine and showing scaffold msg until I delete the content in the input...
So how can I fix this?
Upvotes: 0
Views: 1361
Reputation: 309
I found a solution.
By adding if(value.isNotEmpty)
to the on change error is gone...
Need to check whether value is empty or not.
That's how I solved my problem.
Thank you
general_tab.dart
class GeneralTab extends StatefulWidget {
const GeneralTab({Key? key}) : super(key: key);
@override
State<GeneralTab> createState() => _GeneralTabState();
}
class _GeneralTabState extends State<GeneralTab> {
final SCF _scf = SCF();
@override
Widget build(BuildContext context) {
return Consumer<ProductProvider>(
builder: (context, provider, child) {
return ListView(
padding: const EdgeInsets.all(15.0),
children: [
// Regular Price
FormFieldInput(
label: 'Regular Price',
inputType: TextInputType.number,
onChanged: (value) {
if (value.isNotEmpty) {
provider.getFormData(regularPrice: int.parse(value));
}
},
),
// Sales Price
FormFieldInput(
label: 'Sales Price',
inputType: TextInputType.number,
onChanged: (value) {
if (value.isNotEmpty) {
if (int.parse(value) > provider.productData!['regularPrice']) {
_scf.scaffoldMsg(
context: context,
msg: 'Sales price should be less than regular price',
);
}
}
setState(() {
provider.getFormData(salesPrice: int.parse(value));
});
},
),
],
);
},
);
}
}
Upvotes: 0
Reputation: 331
that's because when the the text is empty the app cast the empty to number so this error happened when you reach the compare , so you need to check if the text is not empty before you trigger the compare.
Upvotes: 1