In this post, let’s learn a few methods to parse/convert String to number (integer, double or both).
1. Use parse() method (not recommended)
/// Parse string to integer
int stringToInt_parse(String input) {
return int.parse(input, onError: (error) {
// Return null if input string is invalid.
// Change to default value if you want.
return null;
});
/// Parse string to double
double stringToDouble_parse(String input) {
return double.parse(input, (error) {
// Return null if input string is invalid.
// Change to default value if you want.
return null;
});
}
/// Parse string to number
num stringToNumber_parse(String input) {
return num.parse(input, (error) {
// Return null if input string is invalid.
// Change to default value if you want.
return null;
});
}
Test it
void main() {
final testInt = '100';
final testDouble = '100.1';
final testInvalidNumber = 'a';
print(stringToInt_parse(testInt)); // 100
print(stringToDouble_parse(testInt)); // 100.0
print(stringToNumber_parse(testInt)); // 100
print(stringToInt_parse(testDouble)); // null
print(stringToDouble_parse(testDouble)); // 100.1
print(stringToNumber_parse(testDouble)); // 100.1
print(stringToInt_parse(testInvalidNumber)); // null
print(stringToDouble_parse(testInvalidNumber)); // null
print(stringToNumber_parse(testInvalidNumber)); // null
}
Notes:
We can use double.parse() to convert a valid integer string to int, but it will return a double (Line 7: 100.0). And obviously we can not convert a valid double string to integer, it will return null (Line 10: null).
With num.parse(), the program will try to parse to integer first, if it can not parse (get null), then it will try to parse to double. (That’s why at line 8, the output is 100 but not 100.0).
I don’t know exactly the reason behind this, but if you look at the signature of the int.parse(), double.parse() and num.parse(), you will see that onError is optional named parameter in int.parse() while with double.parse() and num.parse() it is optional positional parameter. 🤔 🤔 🤔
// Look at onError:
int.parse(input, onError: (error) {
// ...
});
// No need onError:
double.parse(input, (error) {
// ...
});
// No need onError:
num.parse(input, (error) {
// ...
});
- If you don’t provide onError method to handle the exception with invalid string, the program will throw an exception at runtime.
/// Parse string to integer without handling error
/// -> throw exception at runtime.
int stringToInt_parseWithoutErrorHandle(String input) {
return int.parse(input);
}
void main() {
final testInvalidNumber = 'a';
print(stringToInt_parseWithoutErrorHandle(
testInvalidNumber)
);
}
Exception:
Unhandled exception:
FormatException: Invalid radix-10 number (at character 1)
a
^
#0 int._throwFormatException (dart:core-patch/integers_patch.dart:131:5)
#1 int._parseRadix (dart:core-patch/integers_patch.dart:142:16)
#2 int._parse (dart:core-patch/integers_patch.dart:100:12)
#3 int.parse (dart:core-patch/integers_patch.dart:63:12)
#4 stringToInt_parseWithoutErrorHandle (package:dart/core/string/string_to_number.dart:58:14)
#5 main (package:dart/core/string/string_to_number.dart:18:9)
#6 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#7 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
- (Important) At the beginning, I highlighted that this parse() method is not recommended. The dart document says (source):
* ...
* The [onError] parameter is deprecated and will be removed.
* Instead of `int.parse(string, onError: (string) => ...)`,
* you should use `int.tryParse(string) ?? (...)`.
* ...
As mentioned above, we should use tryParse() method instead. Let’s move to that method immediately.
2. Use tryParse() method
When using tryParse() method, we just need to provide the input String. In case the input is invalid, the program will return null. This is the difference between tryParse() and parse() (which throws exception if we don’t handle onError method).
int stringToInt_tryParse(String input) {
return int.tryParse(input);
}
double stringToDouble_tryParse(String input) {
return double.tryParse(input);
}
num stringToNumber_tryParse(String input) {
return num.tryParse(input);
}
Test it
void main() {
final testInt = '100';
final testDouble = '100.1';
final testInvalidNumber = 'a';
print(stringToInt_tryParse(testInt)); // 100
print(stringToDouble_tryParse(testInt)); // 100.0
print(stringToNumber_tryParse(testInt)); // 100
print(stringToDouble_tryParse(testInt)); // 100.0
print(stringToDouble_tryParse(testDouble)); // 100.1
print(stringToNumber_tryParse(testDouble)); // 100.1
print(stringToInt_tryParse(testInvalidNumber)); // null
print(stringToDouble_tryParse(testInvalidNumber)); // null
print(stringToNumber_tryParse(testInvalidNumber)); // null
}
3. (Bonus) Use extension methods
In case you don’t know what extension methods is, it is a way to add more functions to existing libraries/classes. In our case, we use this technique to add 3 methods to String class.
extension StringExtension on String {
int toInt() {
return int.tryParse(this);
}
double toDouble() {
return double.tryParse(this);
}
num toNumber() {
return num.tryParse(this);
}
}
After creating above extension, now our String has 3 more methods that we can use as other exiting methods. So cool! 😎 😎 😎
void main() {
final testInt = '100';
final testDouble = '100.1';
final testInvalidNumber = 'a';
print(testInt.toInt()); // 100
print(testInt.toDouble()); // 100.0
print(testInt.toNumber()); // 100
print(testDouble.toInt()); // null
print(testDouble.toDouble()); // 100.1
print(testDouble.toNumber()); // 100.1
print(testInvalidNumber.toInt()); // null
print(testInvalidNumber.toDouble()); // null
print(testInvalidNumber.toNumber()); // null
}
That’s it!
You can find original article on my blog.
Top comments (0)