how to pass uncertain parameter to method flutter - flutter

I have a method like following:
void reverseWeekdayStatus({alarmClock,sundayIsSelected}){
alarmClock.sundayIsSelected = !alarmClock.sundayIsSelected ?? false;
update();
}
alarmClock is a model:
class AlarmClock {
bool sundayIsSelected;
bool mondayIsSelected;
bool tuesdaySelected;
bool wednesdayIsSelected;
bool thursdayIsSelected;
bool fridayIsSelected;
bool saturdayIsSelected;
AlarmClock({
this.sundayIsSelected = false,
this.mondayIsSelected = false,
this.tuesdaySelected = false,
this.wednesdayIsSelected = false,
this.thursdayIsSelected = false,
this.fridayIsSelected = false,
this.saturdayIsSelected = false,
});
}
so for this method I want to not just sundayIsSelected also the rest like mondayIsSelected could be reversed if I implement this method, what I did is following:
void reverseWeekdayStatus({alarmClock,whichDay}){
alarmClock.whichDay = !alarmClock.whichDay ?? false;
update();
}
And pass mondayIsSelected for example to whichDay, and then I got an error since whichDay does not exist in alarmClock, another way I thought is to create separate methods like from monday to sunday, is there a smarter way to do this job? thanks!

class AlarmClock {
bool sundayIsSelected;
AlarmClock({
this.sundayIsSelected = false,
});
}
On current mode, you are providing default for each field. If you don't pass any value for sundayIsSelected it will get default value false. But sundayIsSelected is not nullable. It can't be null.
Therefore, alarmClock.sundayIsSelected ?? false will never get false.
To reverse, you just like to change the value then do
void reverseWeekdayStatus({
alarmClock,
}) {
alarmClock.sundayIsSelected = !alarmClock.sundayIsSelected;
...
}
It will switch the bool when ever gets call. You can do conditional state on update case, and it is an optional parameter with default value.
void reverseWeekdayStatus({alarmClock, bool switchSundayState = false}) {
if (switchSundayState) {
alarmClock.sundayIsSelected = !alarmClock.sundayIsSelected;
}
}
Another technic is using copyWith constructor, it is nullable (optional) named constructor, use current value if we don't pass value for field.
class AlarmClock {
final bool sundayIsSelected;
AlarmClock({
this.sundayIsSelected = false,
});
AlarmClock copyWith({
bool? sundayIsSelected,
}) {
return AlarmClock(
sundayIsSelected: sundayIsSelected ?? this.sundayIsSelected,
);
}
}
And use cases
alarmClock = alarmClock.copyWith(sundayIsSelected: true);

Related

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.

type 'Null' is not a subtype of type 'bool' in type cast

I have Created a Map<String,bool>(in which the key are of type String and the values are of type Boolean) in flutter and When I want to use the bool values in if condition it give me error saying "A nullable expression can't be used as a condition.
Try checking that the value isn't 'null' before using it as a condition."
When I use "as bool" then the error is gone but the program is not executed properly and give me the error in the pic
//this is the code
Map<String, bool> _userFilters = {
"gluten": false,
"lactose": false,
"vegan": false,
"vegetarian": false,
};
List<Meal> filteredMeal = DUMMY_MEALS;
void saveFilters(Map<String, bool> filteredData) {
setState(() {
_userFilters = filteredData;
filteredMeal = DUMMY_MEALS.where(
(meal) {
if (_userFilters['gluten']as bool) { // _userFilter['gluten'] is giving error
return false;
}
if (_userFilters['lactose']as bool) {
return false;
}
if (_userFilters['vegan']as bool) {
return false;
}
if (_userFilters['vegetarian'] as bool) {
return false;
}
return true;
},
).toList();
});
}
No need to cast your map entries to booleans. use an exclamation mark at the end of your variable (e.g, _usedFilters['gluten']!) to treat it as non-nullable.
Rewrite all your conditions like this (if you're sure that the value won't be null):
if (_userFilters['gluten']!) {
return false;
}
if (_userFilters['lactose']!) {
return false;
}
if (_userFilters['vegan']!) {
return false;
}
if (_userFilters['vegetarian']!) {
return false;
}
From Dart.dev:
“Casting away nullability” comes up often enough that we have a new
shorthand syntax. A postfix exclamation mark (!) takes the expression
on the left and casts it to its underlying non-nullable type.

Dart: Is there a way to negate and return a boolean in a single line?

Is there a way to write the follwoing funciton as a single line, using the fat arrow (=>) notation?
bool tick() {
_tick = !_tick;
return _tick;
}
The following thick() method will negate _tick and return the newly assigned value:
bool tick() => _tick = !_tick;
Simply:
bool tick() => !_tick;
_tick should be defined, and this function will return negated value. So you have to assign the result in order to negate. Like this:
void main() {
bool _tick = true;
_tick = tick(_tick);
print(_tick);
_tick = tick(_tick);
print(_tick);
}
bool tick(tick) => !tick;
The above will print:
false
true
If you'd like to have a variable declared and have this negated in a function you can try:
class Tick {
bool tick;
Tick(this.tick);
}
void tick(Tick data) => data.tick = !data.tick;
main() {
var data = new Tick(true);
print(data.tick); // true
tick(data);
print(data.tick); // false
tick(data);
print(data.tick); // true
}

Getting a changed value within the same class?

I'm trying to access a boolean that gets set outside of the class. When I check the value in the getter, it is correct. But, when I try to access that value from a different method within the same class, I'm getting the old unchanged value.
Is there a way around this or would I need two separate classes to do this? Here's a little snippet of code.
class RoutineProvider with ChangeNotifier {
bool _isNight = false;
set isNight(bool newValue) {
print(newValue); // returns true
_isNight = newValue;
print(_isNight); // returns true
notifyListeners();
}
bool get isNight => _isNight;
Future<Routine> basicRoutine() {
print(RoutineProvider().isNight); // returns false
if (RoutineProvider().isNight) {
return firestore
.collection('routines')
.doc('basic_routine_night')
.get()
.then((snap) => Routine.fromDocSnap(snap));
}
return firestore
.collection('routines')
.doc('basic_routine')
.get()
.then((snap) => Routine.fromDocSnap(snap));
}
}
Calling RoutineProvider() seems like it would instantiate a new RoutineProvider object each time. You could try changing bool _isNight = false to static bool _isNight = false

Can object properties be used as function parameters?

I have a class with several Boolean properties:
class aTest {
String name;
bool twoGroups;
bool continuous;
bool parametric;
bool covariates;
bool paired;
aTest(
{this.name,
this.twoGroups,
this.continuous,
this.parametric,
this.covariates,
this.paired});
} //end aTest
I also have a list with instances of aTest:
List<aTest> testList = [
aTest(
name: "independent samples t-test",
twoGroups: true,
continuous: true,
parametric: true,
covariates: false,
paired: false),
//followed by a bunch of similar objects
]
Elsewhere in my app I filter the List<aTest> with procedures like:
void isParametric(bool value) {
List<aTest> newList = [];
for (aTest test in testList) {
if (test.parametric == value || test.parametric == null) {
newList.add(test);
}
}
testList = newList;
}
void isTwoGroups(bool value) {
List<aTest> newList = [];
for (aTest test in testList) {
if (test.twoGroups == value || test.twoGroups == null) {
newList.add(test);
}
}
testList = newList;
}
(I don't know whether this is the best way to filter and remove objects from the List.) All that differs among these procedures is an object property, e.g., test.parametric and test.twoGroups in the code above.
Is there a way to refactor the code? Something like
void filter (aBooleanPropertyGoesHere, bool value)
You can simply filter with the lists with one liner by where method.
var parametricList = testList.where((i) => (i.continuous && i.parametric == null)).toList()
var twoGroupsList = testList.where((i) => (test.twoGroups == value || test.twoGroups == null)).toList()
Something like this https://dartpad.dev/79a7e9aa5882af745b6ff2cb55815921
For detailed explanation check out the documentation