Dart Function Returning Set<bool> Instead of bool - flutter

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).

Related

Dart - Function Calculate difference of days

i created function in flutter using dart that takes Today date and see if it equal to today or not. and u can use for a week, month..etc
here it is
bool daysPassed(int timeStamp, int days) {
if (DateTime.now()
.difference(DateTime.fromMillisecondsSinceEpoch(timeStamp))
.inDays >=
days) {
return true;
}
return false;
}
so i used this function to see if a one day passed or not , if one day passed make all the variables from shared preference to zero, otherwise get the current variables
here is the logic that i made,
HOME.pref = await SharedPreferences.getInstance();
int? timeStamp = HOME.pref!.getInt('day_timestamp_values_changed');
int? timeStamp1Week = HOME.pref!.getInt('week_timestamp');
setState(() {
if (timeStamp != null) {
if (daysPassed(timeStamp, 1)) {
// 1 means if 1 day is passed
HOME.pref!.setDouble('currentCircleProgressValue', 0);
HOME.pref!.setDouble('currentCircleProgressValue2', 0);
HOME.pref!.setDouble('currentCircleProgressValue3', 0);
HOME.pref!.setInt('iii', 0);
if (HOME.Currentday != 0) {
HOME.Lastday = HOME.pref!.getInt('Currentday')!;
HOME.pref!.setInt('Currentday', 0);
}
} else {
HOME.currentCircleProgressValue =
HOME.pref!.getDouble('currentCircleProgressValue')!;
HOME.currentCircleProgressValue2 =
HOME.pref!.getDouble('currentCircleProgressValue2')!;
HOME.currentCircleProgressValue3 =
HOME.pref!.getDouble('currentCircleProgressValue3')!;
HOME.iii = HOME.pref!.getInt('iii')!;
HOME.Currentday = HOME.pref!.getInt('Currentday')!;
HOME.Lastday = HOME.pref!.getInt('Lastday')!;
}
}
the problem is when i test this out the variables after still the same. nothing happens the variables not initialize to zero.
Can u please help me out ?
Thank u

How do I sort a list of element according to Delivery time of the orders in dart, Flutter?

I am fetching a list of orders and storing the objects in a List. The object has a property called String deliveryTime and the times are in 'hh:mm a' format. I want to sort the list by the deliveryTime of the objects in Ascending order. I created a list of String that has the deliveryTime only and used bubble sort to sort them in ASCENDING order. But I am having trouble sorting the entire list of objects in that order.
NOTE: The list of object has some null & "ASAP" as their deliveryTime value.
Here's the incomplete code:
List<OnlineDeliveryOrder> getSortedOrdersList(
List<OnlineDeliveryOrder> orderList,
) {
List<OnlineDeliveryOrder> tempOrderList = [];
List<DateTime> sortedTimeList = [];
print("List Length before Sort: " + orderList.length.toString());
orderList.forEach((OnlineDeliveryOrder order) {
if (order.deliveryTime != null && order.deliveryTime != "ASAP")
sortedTimeList.add(DateFormat('hh:mm a').parse(order.deliveryTime));
});
sortedTimeList =
sortedTimeList.toSet().toList(); //Taking the unique times only
//Sorting times in asc order using bubble sort algorithm
bool sorted = false;
while (!sorted) {
sorted = true;
for (int i = 0; i < sortedTimeList.length - 1; i++) {
DateTime tempTime;
if (sortedTimeList[i].compareTo(sortedTimeList[i + 1]) == 1) {
// dt1.compareTo(dt2) == 1 if dt1 is a later date than dt2
tempTime = sortedTimeList[i];
sortedTimeList[i] = sortedTimeList[i + 1];
sortedTimeList[i + 1] = tempTime;
sorted = false;
}
}
}
// HOW DO I SORT THE ENTIRE LIST
print("List Length after Sort: " + tempOrderList.length.toString());
// String time = DateFormat('hh:mm a').format(element);
return tempOrderList;
}
Can anyone please guide me on how can I return the sorted list?
Why do you implement a sorting algorithm with O(n^2) time complexity by your own?
You can use
List<OnlineDeliveryOrder> getSortedOrdersList(List<OnlineDeliveryOrder> orderList){
var format = DateFormat('hh:mm a');
return List.of(orderList)..sort((a,b){
if(a.deliveryTime == null) return 1;
if(b.deliveryTime == null) return -1;
if(a.deliveryTime == 'ASAP') return 1;
if(b.deliveryTime == 'ASAP') return -1;
return format.parse(a.deliveryTime).compareTo(format.parse(b.deliveryTime));
});
}
This way, first all objects come with valid date, then with 'ASAP' and then with null as deliveryTime.
Or if you want it even more efficient without any package:
class SortObject extends Comparable<SortObject>{
static final DateFormat format = DateFormat('hh:mm a');
final OnlineDeliveryOrder order;
final DateTime? deliveryTime;
SortObject(this.order):this.deliveryTime=order.deliveryTime==null||order.deliveryTime=='ASAP'?null:format.parse(order.deliveryTime);
int compareTo(SortObject other){
if(order.deliveryTime == null) return 1;
if(other.order.deliveryTime == null) return -1;
if(order.deliveryTime == 'ASAP') return 1;
if(other.order.deliveryTime == 'ASAP') return -1;
return deliveryTime!.compareTo(other.deliveryTime!);
}
}
List<OnlineDeliveryOrder> getSortedOrdersList(List<OnlineDeliveryOrder> orderList){
return (orderList.map((a)=>SortObject(a)).toList()..sort((a,b){
return a.compareTo(b);
})).map((a)=>a.order).toList();
}
Or did I get the question wrong?
If there are errors in the code, I apologize. I just wrote it down.
I would recommend you to add in the OnlineDeliveryOrder class another attribute that stores the DateTime in addition to deliveryTime which does that as a String. Or you can store the time only as DateTime and not as String at all. If you receive the data as JSON, this is very easy to do. (This way you wouldn't need an extra class or a GroupedList).

Can we perform "Not null or return" in flutter with null safety feature?

I'm trying to migrate null safety feature into my Flutter project because it's good for my future of project. Since I already have experience of developing Android app via Kotlin, I already got used to this null safety feature. But it seems I can't perform one thing which can be done in Kotlin.
user?.name ?? "Unknown"
I noticed that in Dart, I can set default value with this code line.
Now I'm trying to perform this
fun performOrReturn(users: Map<String, User>, id: String) {
val user = users[id] ?: return //This line
println("User info gotten : ${user.name}")
}
In Kotlin, I can perform this thing. I can make method return itself if specific variable is null, so Kotlin can handle null safety flexibly.
So here is what I'm trying to do, there is table in my code. I want to check if there is data existing in specified column and row in this field.
Map<int, List<MyData>> table = Map();
...
int _findDataExisting(int row, int col) {
List<MyData> data = table[row]; //This is causing problem because table[row] can be null
//Alternative solution is
//List<MyData> data = table[row] ?? List.empty();
//
//if(data.isEmpty) {
// return -1;
//}
//
for(int i = 0; i < data.length; i++) {
if(data[i].column == col) {
return i;
}
}
return -1;
}
I want to make it return -1 rather than initializing default value because it's not good for handling memory, and code becomes inefficient.
List<MyData> data = map[row] ?? return -1;
I tried line below just like Kotlin, but Dart seems that it can't handle this.
Is there any equivalent thing in Dart? Making it return method if specific variable is null.
Don't be fancy.
int _findDataExisting(int row, int col) {
if (table[row] != null) {
List<MyData> data = table[row]!;
for(int i = 0; i < data.length; i++) {
if(data[i].column == col) {
return i;
}
}
}
return -1;
}
You could initially declare data as nullable and let the null check automatically promote it to a non-nullable type, avoiding the need to use null assertions (!) later:
int _findDataExisting(int row, int col) {
List<MyData>? data = table[row];
if (data == null) return -1;
for (int i = 0; i < data.length; i++) {
if (data[i].column == col) {
return i;
}
}
return -1;
}

Flutter : Why This Method Not Works?

In QuerySnapshot It Has "Day1" and "Day2" Boths are Day of Week Like "Saturday". If "Day1" or "Day2" is Today I need to Return "true". But This method always returns false. I need to know why the If condition (In Loop) is not working and How can I Solve this?
bool class_count(Stream<QuerySnapshot> stream) {
bool class_ = false;
String dateFormat = DateFormat('EEEE').format(DateTime.now());
//This Line Return Day Like "Saturday"
stream.forEach((element) {
if (element != null) {
for (int count = 0; count < element.documents.length; count++) {
if (element.documents[count].data['Day1'].toString() == dateFormat)
class_ = true;
if (element.documents[count].data['Day2'].toString() ==
dateFormat) if (element.documents[count].data['Day2']
.toString() ==
dateFormat) class_ = true;
}
}
});
print(class_);
return class_;
}
Bacause stream's forEach is asynchronous. So this loop will not wait while it completes. In your code you set class_ to false, then create a future which will be executed in future, and return classs_ at once. So it still equal to false.
Try to add async suffix to method and await before stream.forEach. And then your method must return Future<bool> and been called as
final class = await class_count(someStream);
I think the best way to handle stream events is add listener for stream and process data in it.
stream.listener((event) {
// here must be your code which will be executed each time stream will get event
});
stream.forEach() method returns a Future type value. So you have to call this method inside a another Asynchronous function and also it needs to be await until that future completes.
Solution:-
Convert your class_count() synchronous method to a Asynchronous method by,
Adding async keyword to method header.
Change your return type into a Future<bool>.
Add await keyword before stream.forEach() method call (Asynchronous operation).
Code:-
[Read comments carefully to understand the program flow correctly]
//1- Return type should be a Future type => Future<bool>.
//2- Add async keyword before method body => async.
Future<bool> class_count(Stream<QuerySnapshot> stream) async{
bool class_ = false;
String dateFormat = DateFormat('EEEE').format(DateTime.now());
//3 - Adding await keyword before asynchronous operation => await.
//
await stream.forEach((element) {
if (element != null) {
for (int count = 0; count < element.documents.length; count++) {
if (element.documents[count].data['Day1'].toString() == dateFormat)
class_ = true;
if (element.documents[count].data['Day2'].toString() ==
dateFormat) if (element.documents[count].data['Day2']
.toString() ==
dateFormat) class_ = true;
}
}
});
//After stream.forEach() method completes its loop these below statements will execute.
//Every statements inside the function body will only execute one after another.
//so below statements are only executes after the above operation completes.
print(class_);
return class_;
}
One extra tip :- By using StreamSubcription you can get streams of data, instead of future.

12.0 can't be identified as double nor int or numeric in flutter

I have this problem with dart. I created a simple calculator. If the result if a calculation is equal to, for example, -12.9 or 12.9. The app gives the correct answer and no error. But, if the answer given is 12.0 or -12.0, the app crashes. Why is that? I created a function to check if the string is an int or a double. It returns false.
bool isDouble(String number) {
try {
num n = num.parse(number);
if (n % 1 == 0) {
return false;
} else {
return true;
}
} catch (e) {
return false;
}
}
For the numeric, I used the isNumeric function in dart. Please help me.
As Riwen mentioned, any whole number % 1 is 0, even if it's a float. You can check the type of a variable with .runtimeType. I think when you parse the string to num, it automatically converts whole numbers to int, so you cant just check if runtimeType == "double". Also, to remove decimal values, you can just use .floor(), which will round down and convert the variable to an int.
This function seems to work:
bool isDouble(String number) {
if (int.tryParse(number) == null){
if (double.parse(number).isFinite) return true;
}
return false;
}