How can you reload data that is generated through Builder BlocConsumer? - flutter

I tried to write my own action Future using . clear() and re-generate it in the same place, but it didn't work.
For example, it first generates data for the month of the last image (August), selects May and it clears August data and generates for May.
To explain: I get data for several months or years, for example: August 2022, May 2022, December 2021, etc.
To make the code more optimized I want to generate first for the last incoming item, and then when I click on a certain month in the dropdown, deleting the old data to generate new data for the month and year he chose.
#override
Widget build(BuildContext context) {
final _provider = Provider.of<MapRepository>(context);
currentIndicator = _provider.fieldIndicator;
filterLayer = _provider.filterLayer;
selectedMonth = currentIndicator != null ? currentIndicator!.getMonth : "";
selectedYear = currentIndicator != null ? currentIndicator!.getYear : "";
String dateMonth =
currentIndicator != null ? "$selectedMonth $selectedYear" : "Загрузка";
_controller = FixedExtentScrollController(initialItem: 0);
return BlocConsumer(
bloc: indicatorBloc,
listener: (context, state) {
if (state is FetchedIndicatorsState) {
int lastPresent = 0;
Future.delayed(Duration(seconds: 1)).then((value) {
for (int i = 0; i < indicators.length; i++) {
if (indicators.reversed.toList()[i].isPresent) {
lastPresent = i;
}
dates.add(indicators[i].getDateTime);
}
for (var date in dates) {
String shortMonth = DateFormat("MMM", "ru").format(date);
String year = DateFormat("yy", "ru").format(date);
String month =
DateFormat("MMMM", "ru").format(date).toCapitalized();
indicatorDates['$shortMonth$year'] = '$month ${date.year}';
}
selectIndicator(indicators.reversed.toList()[lastPresent]);
});
}
},
builder: (context, state) {
if (state is FetchedIndicatorsState) {
indicators = state.indicators;
for (int i = 0; i < indicators.length; i++) {
if (indicators[i].getMonth == selectedMonth &&
indicators[i].getYear == selectedYear) {
childrenIndicators.add(buildIndicator(
indicators[i], indicators[(i - 1 < 0) ? 0 : (i - 1)], i));
}
}
return buildBody(context, dateMonth, childrenIndicators);
}
return Container();
},
);
}
OnTap actions:
onTap: () {
_refreshData();
setState(() {
selectedYear = entry.value.substring(entry.value.length - 5);
selectedMonth = entry.value.substring(0, entry.value.length - 5);
});
Navigator.pop(context);
},
My action:
Future _refreshData() async {
await Future.delayed(Duration(seconds: 3));
childrenIndicators.clear();
for (int i = 0; i < indicators.length; i++) {
if (indicators[i].getMonth == selectedMonth &&
indicators[i].getYear == selectedYear) {
childrenIndicators.add(buildIndicator(
indicators[i], indicators[(i - 1 < 0) ? 0 : (i - 1)], i));
}
}
setState(() {});
}

Related

Listen to a new value of a bloc and generate a list of listened items

I have this StreamSubscription field called followSubscribtion. It listens if there is a new follower and then calls populateFollower to load follower profile.
followsSubscription =
getBloc(context).followsHandler.stream.listen((value) async {
if (value.status == Status.success) {
await populateFollows();
}
});
});
populateFollows() async{
if (getBloc(context).followsModel.length > 0) {
for (var i = 0; i < getBloc(context).followsModel.length; i++) {
getBloc(context).loadFollowsProfile(getBloc(context).followsModel[i].userId);
break;
}
}
}
This works fine, But I want each profile that will be loaded to be added to a list, How do I do that?
loadFollowsProfile method
loadFollowsProfile(int id , List<UserProfileModel> profileList) {
getFollowsProfileHandler.addNetworkTransformerStream(
Network.getInstance().getUserProfile(id), (_) {
userProfileModelBloc = UserProfileModel.fromJson(_);
profileList.add(userProfileModelBloc);
return userProfileModelBloc;
});
}
You can do this by setting up loadFollowsProfile() to return a UserProfileModel, adding that to a list in the for loop of populateFollows(), and then returning that list from populateFollows().
List<ProfileObject> populateFollows() async{
List<ProfileObject> profileList = [];
if (getBloc(context).followsModel.length > 0) {
for (var i = 0; i < getBloc(context).followsModel.length; i++){
profileList.add(getBloc(context).loadFollowsProfile(
getBloc(context).followsModel[i].userId
));
break;
}
}
return profileList;
}
followsSubscription =
getBloc(context).followsHandler.stream.listen((value) async {
if (value.status == Status.success) {
profileList = await populateFollows();
}
});
});

show data according to number of weeks

i have this ui what i want to achieve is that i want to show data according to the date and also if the number of week is selected 1 then i want to show that same data for seven days from that particular date and after that date i want to remove that item
void chooseDay(CalendarDayModel clickedDay) {
setState(() {
_lastChooseDay = _daysList.indexOf(clickedDay);
for (var day in _daysList) {
day.isChecked = false;
}
CalendarDayModel chooseDay = _daysList[_daysList.indexOf(clickedDay)];
chooseDay.isChecked = true;
dailyPills.clear();
for (var pill in allListOfPills) {
DateTime pillDate =
DateTime.fromMicrosecondsSinceEpoch(pill.time! * 1000);
int? week = pill.howManyWeeks;
int totalDays = week! * 7;
final extraDuration = Duration(days: totalDays);
final startDate = pillDate;
final newDateTime = startDate.add(extraDuration);
if (chooseDay.dayNumber == pillDate.day &&
chooseDay.month == pillDate.month &&
chooseDay.year == pillDate.year) {
log("first condition vhitra");
dailyPills.add(pill);
} else if (pillDate.day + 7 != newDateTime.day + 1) {
dailyPills.add(pill);
} else if (newDateTime.day.isLowerThan(chooseDay.dayNumber!)) {
setState(() {
dailyPills.clear();
});
}
}
dailyPills.sort((pill1, pill2) => pill1.time!.compareTo(pill2.time!));
});
}
this is what i tried need some insight here thanks

XMLHTTPRequest error but only when added to main project

so I have this code:
import 'dart:convert';
import 'package:http/http.dart' as http;
List getMenuDay(String day, List canteenMenu) {
if (day == "tuesday") {
return canteenMenu[0];
}
else if (day == "wednesday") {
return canteenMenu[1];
}
else if (day == "thursday") {
return canteenMenu[2];
}
else if (day == "friday") {
return canteenMenu[3];
}
else if (day == "saturday") {
return canteenMenu[4];
}
else if (day == "sunday") {
return canteenMenu[5];
}
else {
return [];
}
}
String getDayPlate(String day, String plate, List canteenMenu) {
List dayMenu = getMenuDay(day, canteenMenu);
if (plate == "sopa") {
return dayMenu[0];
}
else if (plate == "carne") {
return dayMenu[1];
}
else if (plate == "peixe") {
return dayMenu[2];
}
else if (plate == "dieta") {
return dayMenu[3];
}
else if (plate == "vegetariano") {
return dayMenu[4];
}
return "";
}
void main() async {
List list = [];
List helper = [];
const canteenUrl = 'https://sigarra.up.pt/feup/pt/mob_eme_geral.cantinas';
var response = await http.get(Uri.parse(canteenUrl));
if (response.statusCode == 200) {
var data = json.decode(response.body);
for (int i = 0; i < 4; i++) { // loop through different days
for (int j = 0; j < 5; j++) { // loop through different types of food
var parkInfo = data[3]["ementas"][i]["pratos"][j]["descricao"];
helper.add(parkInfo);
//print(parkInfo);
}
list.add(helper);
helper = [];
//print("--------------");
}
/*
for (int i = 0; i < list.length; i++) {
print(list[i]);
}
*/
print(getDayPlate("thursday", "carne", list));
} else {
throw Exception('Failed to read $canteenUrl');
}
}
and when I just create a new project, type it into the main.dart file and run it, it works fine. But when I add it to make whole project, including other files (making the necessary changed like changing the name of the function, etc), it gives me the XMLHTTPRequest error. What could be causing that? The way I'm calling it withing the main project is as follows:
ElevatedButton(
style: style,
onPressed: () {
CanteenInfo canteen = CanteenInfo("tuesday","sopa");
print(canteen.getDayPlate());
},
child: const Text('ShowLen (WIP)'),
Thanks for any help you could give!
Edit 1: I do get a warning when running just the code,
lib/main.dart: Warning: Interpreting this as package URI, 'package:new_test/main.dart'.

Confused about how to work around fl graphs and provider

I'm trying to create an app where there is a button, and when a user clicks on that button, that day's timestamp is recorded and is uploaded in firestore. And then I fetch the data from there and update a fl chart widget.
This is how I get the data from firebase, convert it to DateTime and send it to the graph building method.
Future<void> updateOfflineGraph(String uid) async {
//GraphData graphData = globalContext.watch<GraphData>();
GraphData graphData = GraphData();
List<dynamic> today = List<dynamic>();
List<DateTime> now = List<DateTime>();
try {
DocumentSnapshot _docSnapshot =
await _firestore.collection("graph").document(uid).get();
today.addAll(_docSnapshot.data()['dates']);
for (int i = 0; i < today.length; i++) {
now.add(DateTime.fromMicrosecondsSinceEpoch(
today[i].microsecondsSinceEpoch));
}
graphData.buildGraph(now);
} catch (e) {
print(e);
}
}
And this is how I process the data for the fl chart.
class GraphData with ChangeNotifier {
List<FlSpot> _data = List<FlSpot>();
List<int> _date = List<int>();
List<FlSpot> get data =>
List.unmodifiable(_data..sort((a, b) => a.x.compareTo(b.x)));
void addPoint(FlSpot spot) {
_data.add(spot);
notifyListeners();
}
void buildGraph(List<DateTime> dateTime) {
removeAllPoints();
int days = 0;
int month = dateTime[0].month;
for (int i = 0; i < dateTime.length; i++) {
if (dateTime[i].month == month) {
days++;
} else {
addMonth(days, month);
days = 0;
month = dateTime[i].month;
i--;
}
}
addMonth(days, month);
}
void addMonth(int days, int month) {
addPoint(FlSpot(month.toDouble(), days.toDouble()));
print(days);
print(month);
print(_data.length);
}
}
And then do this to update the graph.
LineChartBarData(
spots:
// [
// FlSpot(1, 3),
// FlSpot(2, 4),
// FlSpot(4, 5.5),
// FlSpot(5, 1),
// FlSpot(8, 4),
// FlSpot(12, 3),
// ],
context.watch<GraphData>().data.length > 0
? context.watch<GraphData>().data
: [FlSpot(0.0, 0.0)],
}
The problem that I'm facing is that when I do this whole thing, the points are stored in the _data list successfully, but when I try to call spots in LineChartBarData, it says that _data is null when it is called. I don't know why is this happening as the data was there in an iteration before.

Customized Picker of Flutter Datetime Picker

I'm trying to use customized datepicker with creating CustomPicker class as is on Readme.
The problem is the callback of onChanged and onConfirm does not return the updated date. However when I change DatePicker.showPicker to DatePicker.showDatePicker, the callback returns the correct date.
I'm using the following code. I spent hours to investigate this but no luck.
class CustomPicker extends CommonPickerModel {
CustomPicker({DateTime currentTime, LocaleType locale})
: super(locale: locale) {
this.currentTime = currentTime ?? DateTime.now();
}
String yearDigits(int value) {
return '$value';
}
String monthDigits(int value) {
return '$value';
}
#override
String leftStringAtIndex(int index) {
return index >= DateTime.now().year - 100 &&
index <= DateTime.now().year - 18
? '$index'
: null;
}
#override
String middleStringAtIndex(int index) {
return index <= 12 && index >= 1 ? monthDigits(index) : null;
}
#override
String rightStringAtIndex(int index) {
return null;
}
#override
String leftDivider() {
return '';
}
#override
String rightDivider() {
return '';
}
#override
List<int> layoutProportions() {
return [1, 1, 0];
}
#override
DateTime finalTime() {
return currentTime.isUtc
? DateTime.utc(currentTime.year, currentTime.month, 1, 0, 0, 0)
: DateTime(currentTime.month, currentTime.month, 1, 0, 0, 0);
}
}
DatePicker.showPicker(
// ↑ When I change this to DatePicker.showDatePicker
// and comment out pickerModel, the value of print(dateTime) gets selected value.
context,
showTitleActions: true,
onConfirm: (dateTime) {
print(dateTime); // output same value and not updated one
},
pickerModel: CustomPicker(
currentTime: DateTime(_birthYear, _birthMonth, 1),
),
locale: LocaleType.en
);
Okay. So I am not an expert with the Flutter DateTime Picker package but I needed it for a project and so needed to figure out a way for the custom picker, and here is how I solved it.
I realized the issue was with the finalTime() method and what it returns.
I checked the implementation on the package's Github - https://github.com/Realank/flutter_datetime_picker/blob/0b0be9623e905299befc10569f83f3bd11b36125/lib/src/date_model.dart#L494 and picked the sample model for both date & time. It still didn't work until I made sure to update the current left index and the current middle index.
I don't know if my approach is the best, but here is how I solved it.
Here is my solution:
I updated the _currentLeftIndex variable in the setLeftIndex() method:
void setLeftIndex(int index) {
print('left index: '+index.toString());
_currentLeftIndex = index;
....
and then updated the _currentMiddleIndex variable in the setMiddleIndex() method:
void setMiddleIndex(int index) {
print('middle index: '+index.toString());
_currentMiddleIndex = index;
....
Find the full code implementation below:
Note: Remember to import 'date_format.dart'.
...
import 'package:flutter_datetime_picker/src/date_format.dart';
class CustomPicker extends CommonPickerModel {
List<String> leftList;
List<String> middleList;
List<String> rightList;
DateTime currentTime;
int _currentLeftIndex;
int _currentMiddleIndex;
int _currentRightIndex;
LocaleType locale;
DateTime maxTime;
DateTime minTime;
CustomPicker({DateTime currentTime, DateTime maxTime, DateTime minTime, LocaleType locale})
: super(locale: locale) {
this.currentTime = currentTime ?? DateTime.now();
_currentLeftIndex = 0;
_currentMiddleIndex = this.currentTime.hour;
_currentRightIndex = this.currentTime.minute;
this.setLeftIndex(0);
this.setMiddleIndex(this.currentTime.hour);
this.setRightIndex(this.currentTime.minute);
if (currentTime != null) {
this.currentTime = currentTime ?? DateTime.now();
if (maxTime != null &&
(currentTime.isBefore(maxTime) || currentTime.isAtSameMomentAs(maxTime))) {
this.maxTime = maxTime;
}
if (minTime != null &&
(currentTime.isAfter(minTime) || currentTime.isAtSameMomentAs(minTime))) {
this.minTime = minTime;
}
} else {
this.maxTime = maxTime;
this.minTime = minTime;
var now = DateTime.now();
if (this.minTime != null && this.minTime.isAfter(now)) {
this.currentTime = this.minTime;
} else if (this.maxTime != null && this.maxTime.isBefore(now)) {
this.currentTime = this.maxTime;
} else {
this.currentTime = now;
}
}
if (this.minTime != null && this.maxTime != null && this.maxTime.isBefore(this.minTime)) {
// invalid
this.minTime = null;
this.maxTime = null;
}
if (this.minTime != null && isAtSameDay(this.minTime, this.currentTime)) {
_currentMiddleIndex = this.currentTime.hour - this.minTime.hour;
if (_currentMiddleIndex == 0) {
_currentRightIndex = this.currentTime.minute - this.minTime.minute;
}
}
}
bool isAtSameDay(DateTime day1, DateTime day2) {
return day1 != null &&
day2 != null &&
day1.difference(day2).inDays == 0 &&
day1.day == day2.day;
}
#override
void setLeftIndex(int index) {
print('left index: '+index.toString());
_currentLeftIndex = index;
// TODO: implement setLeftIndex
super.setLeftIndex(index);
DateTime time = currentTime.add(Duration(days: index));
if (isAtSameDay(minTime, time)) {
var index = min(24 - minTime.hour - 1, _currentMiddleIndex);
this.setMiddleIndex(index);
} else if (isAtSameDay(maxTime, time)) {
var index = min(maxTime.hour, _currentMiddleIndex);
this.setMiddleIndex(index);
}
}
#override
void setMiddleIndex(int index) {
print('middle index: '+index.toString());
_currentMiddleIndex = index;
// TODO: implement setMiddleIndex
super.setMiddleIndex(index);
DateTime time = currentTime.add(Duration(days: _currentLeftIndex));
if (isAtSameDay(minTime, time) && index == 0) {
var maxIndex = 60 - minTime.minute - 1;
if (_currentRightIndex > maxIndex) {
_currentRightIndex = maxIndex;
}
} else if (isAtSameDay(maxTime, time) && _currentMiddleIndex == maxTime.hour) {
var maxIndex = maxTime.minute;
if (_currentRightIndex > maxIndex) {
_currentRightIndex = maxIndex;
}
}
}
#override
String leftStringAtIndex(int index) {
print('left string index: '+index.toString());
DateTime time = currentTime.add(Duration(days: index));
if (minTime != null && time.isBefore(minTime) && !isAtSameDay(minTime, time)) {
return null;
} else if (maxTime != null && time.isAfter(maxTime) && !isAtSameDay(maxTime, time)) {
return null;
}
return formatDate(time, [ymdw], locale);
}
#override
String middleStringAtIndex(int index) {
print('middle string index: '+index.toString());
if (index >= 0 && index < 24) {
DateTime time = currentTime.add(Duration(days: _currentLeftIndex));
if (isAtSameDay(minTime, time)) {
if (index >= 0 && index < 24 - minTime.hour) {
return digits(minTime.hour + index, 2);
} else {
return null;
}
} else if (isAtSameDay(maxTime, time)) {
if (index >= 0 && index <= maxTime.hour) {
return digits(index, 2);
} else {
return null;
}
}
return digits(index, 2);
}
return null;
}
#override
String rightStringAtIndex(int index) {
print('right string index: '+index.toString());
if (index >= 0 && index < 60) {
DateTime time = currentTime.add(Duration(days: _currentLeftIndex));
if (isAtSameDay(minTime, time) && _currentMiddleIndex == 0) {
if (index >= 0 && index < 60 - minTime.minute) {
return digits(minTime.minute + index, 2);
} else {
return null;
}
} else if (isAtSameDay(maxTime, time) && _currentMiddleIndex >= maxTime.hour) {
if (index >= 0 && index <= maxTime.minute) {
return digits(index, 2);
} else {
return null;
}
}
return digits(index, 2);
}
return null;
}
#override
DateTime finalTime() {
print('all index: ');
print('left index: '+_currentLeftIndex.toString());
print('middle index: '+_currentMiddleIndex.toString());
print('right index: '+_currentRightIndex.toString());
DateTime time = currentTime.add(Duration(days: _currentLeftIndex));
var hour = _currentMiddleIndex;
var minute = _currentRightIndex;
if (isAtSameDay(minTime, time)) {
hour += minTime.hour;
if (minTime.hour == hour) {
minute += minTime.minute;
}
}
return currentTime.isUtc
? DateTime.utc(time.year, time.month, time.day, hour, minute)
: DateTime(time.year, time.month, time.day, hour, minute);
}
#override
List<int> layoutProportions() {
return [4, 1, 1];
}
#override
String rightDivider() {
return ':';
}
}