How to set default value in function - flutter

I try to set default value in function:
bool isOnGoing([DateTime date = DateTime.now()]) {
...
}
But studio returns "Default values of an optional parameter must be constant".
How can I set default parameter in this case?

The syntax you use is correct, but as the error message says, the value has to be a compile time constant.
A compile time constant doesn't make sense for DateTime.now().
As a workaround, you can use:
/// Returns `true` is still going on.
///
/// [date] the date to check.
/// as default value `DateTime.now()` is used
/// if no value or `null` was passed.
bool isOnGoing([DateTime date]) {
date ??= DateTime.now();
...
}

When you have multiple parameters use like below
int findVolume(int length, int breadth, {int height = 4}) {
return length*breadth*height;
}
void main() {
var result = findVolume(2, 3);
print(result);
print("");
//Overriding the default parameter
var result2 = findVolume(1, 2, height: 5);
print(result2);
}
*===== output ======*
24
10
If you use [ ] instead of { } to declare local variables in function,
int findVolume(int length, int breadth, [int height = 12]) {
return length*breadth*height;
}
===== you can call like below ======
findVolume(3, 6);
findVolume(3, 6, 5);
All credits go to:- https://flutterrdart.com/dart-optional-default-parameters-function/

Related

Dart Function Returning Set<bool> Instead of bool

I'm building a mobile client for a blog with a paid CMS that shows a number of articles all the time, plus a rotating article each week, and I've built a simple function to get the current week of the year and return a Boolean value if an article should be displayed this week:
bool displayArticle(StoredArticle article){
if (article.week < 0) {
return true;
}
DateTime now = DateTime.now();
DateTime janFirst = DateTime(now.year, 1, 1);
int weekNum = (now.difference(janFirst).inDays / 7).ceil();
if(article.week == weekNum || article.week == (weekNum - 1)){
return true;
}
return false;
}
I then use this function to filter a list of all the articles like so:
List<StoredArticle> articlessToDisplay = storedArticleObjs.where((article) => {
displayArticle(article)
}).toList();
This is all enclosed within a Stateful Widget.
However, using the function like this throws an error at the function call that The return type 'Set<bool>' isn't a 'bool', as required by the closure's context.
My first thought was that there was an issue with the displayArticle() function being a static member function to a stateful widget, but moving the function directly into the closure as follows did not impact the error.
List<StoredArticle> articlessToDisplay = storedArticleObjs.where((article) => {
if (article.week < 0) {
return true;
}
DateTime now = DateTime.now();
DateTime janFirst = DateTime(now.year, 1, 1);
int weekNum = (now.difference(janFirst).inDays / 7).ceil();
if(article.week == weekNum || article.week == (weekNum - 1)){
return true;
}
return false;
}).toList();
Next I thought it might be that the early return was confusing the inspector to belive it was returning multiple values, so I converted it to a single return function as follows, but that did nothing either.
bool displayArticle(StoredArticle article){
bool shouldDisplay = false;
if (article.week < 0) {
shouldDisplay = true;
}
DateTime now = DateTime.now();
DateTime janFirst = DateTime(now.year, 1, 1);
int weekNum = (now.difference(janFirst).inDays / 7).ceil();
if(article.week == weekNum || article.week == (weekNum - 1)){
shouldDisplay = true;
}
return shouldDisplay;
The only resources on similar issues have been referring to functions that return Future<T> instead of T. Putting aside the fact that my issue is with a Set<T> rather than a Future<T>, those errors have all been thrown by the return statement or the function definition rather than the function call.
I haven't been able to find any resources relating to this specific issue, though as I'm new to Flutter and Dart I suppose could be missing some specific terminology.
That being said, returning a set of the return type does not make any sense to me. Is this a quirk of implementation in a Stateful Widget?
The problem is that you have a few too many braces, and {"A"} is set-syntax in Dart.
You have:
storedArticleObjs.where((article) => {
displayArticle(article)
}).
Change that to:
storedArticleObjs.where((article) =>
displayArticle(article)
).
Note that the => function syntax doesn't use braces.
You could even probably write it more compactly using tear-offs like so:
storedArticleObjs.where(displayArticle).

Why does the identityHashCode function not work for the built-in type 'int' in Dart?

The documentation of the identityHashCode says:
And it indeed works for my custom type 'Integer':
class Integer {
int num;
Integer(this.num);
#override
int get hashCode {
return num;
}
#override
bool operator ==(Object other) {
if(other is Integer && this.num == other.num) {
return true;
}
return false;
}
}
void main() {
Integer n1 = Integer(1);
print(n1.hashCode); // print "1"
print(identityHashCode(n1)); // print "650939380", a different value!
}
But for the built-in type 'int', identityHashCode(int) seems to always return the same value as int.hashCode, which is the numerical value itself:
void main() {
int n = 1;
print(n.hashCode); // print "1"
print(identityHashCode(n)); // still print "1", the same value as n.hashCode!
}
Anyone know why this is happening? I'm confused now.😵
int is Built-in type (not a usual class)
In documentation identityHashCode has a note:
This hash code is compatible with [identical], which just means that
it's guaranteed to be stable over time.
For compiler all int values are constants. identical for the same constants shows true. So hashCode of int was made by own value (which also int).
print(identical(1, 1)); // true
According to this comment int (and double) has own condition for comparing in identical function.
By the same numeric value
Here's some code for example representation:
void main() {
int a = 1; // '1' is a constant
int b = 1;
int c = 2; // '2' is a constant
print(identical(a, b)); // true
print(identical(a, c)); // false
print(identical(1, 1)); // true
print(identical(1, 2)); // false <= 1 and 2 are constants
print(identical(a, 1)); // true
print(identical(c, 1)); // false
print(identical(c, 2)); // true
print(identityHashCode(a)); // 1
print(identityHashCode(b)); // 1
print(identityHashCode(c)); // 2
print(identityHashCode(1)); // 1
print(identityHashCode(2)); // 2
}

How do I make the map value a constant in function parameter in dart

Why does dart complain "The default value of an optional parameter must be constant". How do I make the map value constant
Map<String, int> toastDuration = {
"defaut": 4000,
};
void showToast({
BuildContext context,
String msg,
int msDuration = toastDuration["default"], // Error: The default value of an optional parameter must be constant
bool hidePrev = true,
}) {
....
}
I tried adding const but that didn't work as it expects map part to be a class.
int msDuration = const toastDuration["default"],
toastDuration["default"] can't be constant because it's an expression calculated later (Think about the fact you can put any string in the braces). You can do something similar like that:
const defaultToastDuration = 4000;
Map<String, int> toastDuration = {
"default": defaultToastDuration,
}
void showToast({
BuildContext context,
String msg,
int msDuration = defaultToastDuration,
bool hidePrev = true,
}) {
...
}
As the error message says The default value of an optional parameter must be constant. Think about what happens if you remove the default key from toastDuration. Instead of using a map here you can simply use the default value directly.
void showToast({
BuildContext context,
String msg,
int msDuration = 4000,
bool hidePrev = true,
})
Another problem in your original code is that if you change the default key to say 300, the showToast will break because default parameters must be constants.

Passing null vs nothing to named parameters

This is my class:
class Source {
final int value;
Source({this.value = 1}) {
print("source = $value");
}
}
This is how I'm passing values:
Source(value: null); // prints null
Source(); // prints 1
The question is if I am passing null to value in first call, why doesn't it print 1, aren't they equivalent?
In your definition you are creating a default parameter.
value is being defined as 1 and will be the default value in the absence of any other value being assigned to that parameter. When you actively provide it null as a value, it takes precedence over the default.
#adlopez15 is the correct answer.
But if you want null to result in 1 you can do this:
class Source {
final int value;
Source({int value}) : value = value ?? 1 {
print("source = ${this.value}");
}
}

Flutter double to Time in hours

I'm trying to convert a double value (e.g. 9.5) to a corresponding hour/minute value (e.g. 9.30). I also want to perform calculations using this value, but handle it like a time value (e.g. adding 23 and 2 should result in 1 as the hours should wrap around at 24 hours).
I already tried to convert the value to DateTime, but it says "invalid date format".
This should do it
void main() {
print(getTimeStringFromDouble(9.5)); // 9:30
print(getTimeStringFromDouble(25.0)); // 1:0
}
String getTimeStringFromDouble(double value) {
if (value < 0) return 'Invalid Value';
int flooredValue = value.floor();
double decimalValue = value - flooredValue;
String hourValue = getHourString(flooredValue);
String minuteString = getMinuteString(decimalValue);
return '$hourValue:$minuteString';
}
String getMinuteString(double decimalValue) {
return '${(decimalValue * 60).toInt()}'.padLeft(2, '0');
}
String getHourString(int flooredValue) {
return '${flooredValue % 24}'.padLeft(2, '0');
}