Getting a changed value within the same class? - flutter

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

Related

Flutter: find item in list of maps and update it

I have 3 nested collections (portfolios, rents and leases) and I get the last one like this:
getRentLeases() {
final portfolio = list.where((portfolio) {
return portfolio['documentID'].contains(currentPortfolioId)
? true
: false;
}).toList();
final rent = portfolio[0]['rents'].where((rent) {
return rent['documentID'].contains(currentRentId) ? true : false;
}).toList();
return rent[0]['leases'];
}
as you see I always have the ID for previous collection saved.
To find a specific lease I could follow similar approach:
var lease = getRentLeases().where((lease) {
return lease['documentID'].contains(newLease['documentID'])
? true
: false;
}).toList();
but how could I update it? Something like this doesn't work:
lease = newLease;
? true : false is not necessary as contains already gives you a boolean value.
If you only expect one item to be returned by the where method, then you should go for singleWhere as it directly gives you the item instead of the list. If none of these or multiple items satisfy the condition, you get an exception.
You should separate getRentLeases into two methods. In this case its even better to have methods returning the index of the relevant item.
Please consider that I only used dynamic because I don't have access to the data types. You should instead type the variables.
Code:
int getIndexOfPortFolio(String portfolioId) {
return list
.indexWhere(portfolio => portfolio['documentID'].contains(portfolioId));
}
int getIndexOfRent(dynamic portfolio, String rentId) {
return portfolio['rents']
.indexWhere(rent => rent['documentID'].toString().contains(rentId));
}
int getIndexOfLease(dynamic rent, String leaseId) {
return rent['leases']
.indexWhere(lease => lease['documentID'].toString().contains(leaseId));
}
And then you can update your object like this:
void updateLease(String portfolioId, String rentId, String oldLeaseId, dynamic newLease) {
int portFolioIndex = getIndexOfPortFolio(portfolioId);
var portFolio = list[portFolioIndex];
int rentIndex = getIndexOfRent(portFolio, rentId);
var rent = portFolio["rents"][rentIndex];
int leaseIndex = getIndexOfLease(rent, oldLeaseId);
rent["leases"][leaseIndex] = newLease;
}

how to pass uncertain parameter to method 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);

How to use a variable for method name

I want to use a variable to access a certain value in my hive database:
In the code below if I use myBox.getAt(i).attributeSelect I get an error because attributeSelect is not defined for the box.
If I use myBox.getAt(i).test it works. How can I make flutter recognise that attributeSelect is a variable and put the value there? I have a total of 181 different variables the user can choose from. Do I really need that many if clauses? The variables are booleans. So I want to check if that attribute is true for the document at index i.
Error: NoSuchMethodError: 'attributeSelect'
method not found
Receiver: Instance of 'HiveDocMod'
attributeSelect = 'test'; //value depends on user choice
Future<void> queryHiveDocs() async {
final myBox = await Hive.openBox('my');
for (var i = 0; i < myBox.length; i++) {
if (attributeSelect == 'All Documents') {
_hiveDocs.add(myBox.getAt(i)); // get all documents
//print(myBox.getAt(24).vesselId);
} else {
// Query for attribute
if (myBox.getAt(i).attributeSelect) {
_hiveDocs.add(myBox.getAt(i)); // get only docs where the attributeSelect is true
}
}
}
setState(() {
_hiveDocs = _hiveDocs;
_isLoading = false;
});
}
I solved it the annoyingly hard way:
if (attributeSelect == 'crsAirCompressor') {
if (myBox.getAt(i).crsAirCompressor) {
_hiveDocs.add(myBox.getAt(i));
}
} else if (attributeSelect == 'crsBatteries') {
if (myBox.getAt(i).crsBatteries) {
_hiveDocs.add(myBox.getAt(i));
}...

error: Only static members can be accessed in initializers

i will import images BASE64 stored in DB.
code :
profileimage()async{
var userimage1 = await DBHelper().getuserIMAGE1('roro');
print(userimage1);
if(userimage1 == Null){
print('Empty');
}else{
setState(() {
userimage1.map((e) {
tmpimage = e['image0'];
}).toList();
print(tmpimage);
_TmpBytesImage = Base64Decoder().convert(tmpimage);
print(_TmpBytesImage);
return Image.memory(_TmpBytesImage);
});
}
}
File pimage = profileimage(); << error
and i got error 'flutter: Only static members can be accessed in initializers'
how can i do?
You need to call like below.
Future.delayed(Duration.zero, () {
// your code
});
The following items appear wrong:
Your return statement is inside a setstate() function so returns a value from that function.
processImage probably should be
Static Future processImage()
The call should be something like below but not at class level. It also needs to of type Image not of type File.
pimage = await processImage();
If there is nothing in the database, what do you want to return?

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