Class 'int' has no instance getter 'millisecondsSinceEpoch' - flutter

i want to build a syncfusion chart in flutter. i retrive data from firebase realtime database. the data would be show in the chart. and i got a problem here. they say about 'millisecondsSinceEpoch'. but i don't have it in my code. but there's got a problem. this is my code :
import 'dart:async';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class Chart extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: HolyChart(),
),
);
}
}
class HolyChart extends StatefulWidget {
#override
_HolyChartState createState() => _HolyChartState();
}
class _HolyChartState extends State<HolyChart> {
Timer _timer;
int _count = 0;
ChartSeriesController _seriesController;
final _dbReference = FirebaseDatabase.instance.reference();
List _chartData = <ChartData>[];
int _values;
#override
void dispose() {
_timer?.cancel();
super.dispose();
}
_updateData(Timer timer) {
_chartData.add(ChartData(_count, _values));
if (_chartData.length == 20) {
_chartData.removeAt(0);
_seriesController.updateDataSource(
addedDataIndexes: <int>[_chartData.length - 1],
removedDataIndexes: <int>[0]);
}
_count = _count + 1;
}
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _dbReference.child("Data").onValue,
builder: (context, snapshot) {
Widget widget;
if (snapshot.hasData &&
!snapshot.hasError &&
snapshot.data.snapshot.value != null) {
_values = snapshot.data.snapshot.value["Moisture"];
if (_values != null) {
_timer = Timer.periodic(Duration(seconds: 3), _updateData(_timer));
}
widget = Container(
child: SfCartesianChart(
tooltipBehavior: TooltipBehavior(enable: true),
primaryXAxis: DateTimeAxis(),
series: <LineSeries<ChartData, int>>[
LineSeries<ChartData, int>(
dataSource: _chartData,
xValueMapper: (ChartData data, _) => data.xAxisValue,
yValueMapper: (ChartData data, _) => data.yAxisValue,
)
],
),
);
} else {
widget = Center(child: CircularProgressIndicator());
}
return widget;
},
);
}
}
class ChartData {
ChartData(this.xAxisValue, this.yAxisValue);
ChartData.fromMap(this.xAxisValue, this.yAxisValue);
final int xAxisValue;
final int yAxisValue;
}
and this is the problem for my code. what's mean with the function 'millisecondsSinceEpoch'? b
The following NoSuchMethodError was thrown building LayoutBuilder:
Class 'int' has no instance getter 'millisecondsSinceEpoch'.
Receiver: 0
Tried calling: millisecondsSinceEpoch
can anyone help me??
thank you so much for your help...

Thanks for the interest in our Flutter charts. We have analyzed your query and the given code and would like to tell you that you are using the DateTimeAxis for the primaryXAxis but your data source values are not a DateTime value. So, kindly use NumericAxis in the chart to process numeric data. To know more about our charts, please find the help document.
Thanks,
Dharanitharan. P

My guess is that you use primaryXAxis: DateTimeAxis(), but none of your x/y value is a Date.
The SfCartesianChart tries to convert x or y as a date (millisecondsSinceEpoch is relative to the usage of a date) but both of them are int.
Have a look at this (search for DateTimeAxis, there is different examples) : https://help.syncfusion.com/flutter/cartesian-charts/axis-customization

Related

unable to pass instance to the initializer [duplicate]

This question already has answers here:
Error: The instance member ... can't be accessed in an initializer
(4 answers)
Closed 3 months ago.
Error : The instance member 'widget' can't be accessed in an initializer.
Im creating a bar chart with getx controller, i want to retrieve values from firebase and pass it to barchart to show it to the user. But the main problem here is that the variable of string could not pass into the controller, can i have a guidance on how to pass it? none of the guidance help me, i really need the help
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:fyp/storage/OrderStats.dart';
import 'package:fyp/storage/OrderStatsController.dart';
import 'package:get/get.dart';
class testChart extends StatefulWidget {
final String? salesDate;
testChart({required this.salesDate});
#override
State<testChart> createState() => _testChartState();
}
class _testChartState extends State<testChart> {
String sales = "11.2022 Sales";
final OrderStatsController orderStatsController = Get.put(OrderStatsController(salesDate: '11.2022 Sales'));
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bar Chart'),
),
body: SizedBox(height: 300,
child:
FutureBuilder(
future: orderStatsController.stats.value,
builder: (BuildContext context, AsyncSnapshot<List<OrderStats>>
snapshot){
if(snapshot.hasData){
return Container(
height: 250,
child: CustomBarChart(orderStats: snapshot.data!, sales: widget.salesDate.toString()),
);
}
else if(snapshot.hasError){
return Text('${snapshot.error}');
}
else{
return Center(child: CircularProgressIndicator(),);
}
},
)
// CustomBarChart(orderStats: OrderStats.data,),
),
);
}
}
class CustomBarChart extends StatefulWidget {
CustomBarChart({Key? key, required this.orderStats, required this.sales}) : super(key: key);
final List<OrderStats> orderStats;
final String sales;
#override
State<CustomBarChart> createState() => _CustomBarChartState();
}
class _CustomBarChartState extends State<CustomBarChart> {
late String salesDate = '11.2022 Sales';
final OrderStatsController orderStatsController = Get.put(OrderStatsController(salesDate: widget.sales.toString()));
#override
Widget build(BuildContext context) {
List<charts.Series<OrderStats, String>> series = [
charts.Series(
id: 'sales',
data: widget.orderStats,
domainFn: (series, _) => series.serviceName.toString(),
measureFn: (series, _) => series.sales,
)
];
return charts.BarChart(series, animate: true,);
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fyp/storage/OrderStats.dart';
import 'package:get/get.dart';
import 'storageService.dart';
class OrderStatsController extends GetxController{
final String salesDate;
OrderStatsController({required this.salesDate});
final Storage storage = Storage();
var stats = Future.value(<OrderStats>[]).obs;
#override
void onInit(){
stats.value = FirebaseFirestore.instance.
collection(salesDate).get().then((querySnapshot) =>
querySnapshot.docs.asMap().entries.map((entry) =>
OrderStats.fromSnapshot(entry.value, entry.key)).toList());
super.onInit();
}
}
right now i only tried passing just "sales", it is fixed, i cannot pass in any variable such as String type
You can define your controller like this:
late OrderStatsController orderStatsController;
then pass your value in initState :
#override
void initState() {
super.initState();
orderStatsController = Get.put(OrderStatsController(salesDate: sales));
}

Random parameter for FutureBuilder

Here I have a StatefulWidget in which I want to get a random pet each time from a random url. Also, I have a condition for the random pet, if the condition is true, the pet will be shown, otherwise the random url and random pet should be selected again. I attached my code below, and the problem is the url only changes when the condition is false, but I want it to be randomly selected each time.
Putting the API.get_pets(init_random_url); in the future parameter of the FutureBuilder will solve the random selection but if the condition is false the URL and the pet would change two or three times, after searching about it and reading FutureBuilder documentation I put it in the initState and requestAgain and build, but I recognized the selectedURL in the build function does not work and the widget is stucked in the same URL until the condition gets false value.
import 'dart:developer';
import 'package:double_back_to_close/toast.dart';
import 'package:flutter/material.dart';
import 'package:pet_store/widgets/guess_game_random_card.dart';
import 'webservice/API.dart';
import 'main.dart';
import 'dart:math';
import 'utils/utils.dart';
Random random = new Random();
class Guess_Game extends StatefulWidget {
const Guess_Game({Key? key}) : super(key: key);
#override
State<Guess_Game> createState() => _Guess_GameState();
}
class _Guess_GameState extends State<Guess_Game> {
void initState() {
super.initState();
init_random_url = randomly_select_URL();
GuessGameFuture = API.get_pets(init_random_url);
}
void requestAgain() {
setState(() {
init_random_url = randomly_select_URL();
GuessGameFuture = API.get_pets(init_random_url);
});
}
#override
Widget build(BuildContext context) {
init_random_url = randomly_select_URL();
return Scaffold(
body: Center(
child:
FutureBuilder<List<dynamic>>(
future: GuessGameFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic>? pet_data = snapshot.data;
var number_of_parameters = snapshot.data!.length;
var random_pet = random.nextInt(number_of_parameters);
var category = pet_data![random_pet].category.toString();
var photoURL = pet_data![random_pet].photoUrls;
// Here is the condition that ensure pet category is in the list and has an image
if (checkCategoryInList(category, items) &&
photoURL.length != 0) {
return Random_Card(
pet_data: pet_data,
random_pet: random_pet,
dropdownvalue: dropdownvalue);
} else {
if (photoURL.length == 0) {
print(" NO PHOTO SUBMITTED FOR THIS PET");
} else {
print(category + "NOT IN CATEGORY");
}
WidgetsBinding.instance.addPostFrameCallback((_) {
requestAgain();
});
}
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const CircularProgressIndicator();
},
)
else
const Text(
"Please select your guess",
style: TextStyle(fontSize: 17, color: Colors.indigo),
),
),
),
}
}
Add this line to build
GuessGameFuture = API.get_pets(randomly_select_URL());
and Change requestAgain function to this:
void requestAgain() {
setState(() {
GuessGameFuture = API.get_pets(randomly_select_URL());
});
}
Also you can use FutureProvider and riverpod library.
Hope it helps

Unable to fetch the selected value of Fortune Wheel

I am using the Fortune Wheel in this link. When I fling the wheel, it will spin and end but when it is done, I'm unable to fetch the value of the selection.
Here's what I have tried:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
class SpinawheelWidget extends StatefulWidget {
#override
State<StatefulWidget> createState() => SpinawheelState();
}
class SpinawheelState extends State<SpinawheelWidget> {
StreamController<int> selected = StreamController<int>();
#override
void initState() {
super.initState();
}
#override
void dispose() {
selected.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
final items = <String>[
'item1',
'item2',
'item3',
'item4',
'item5',
'item6',
];
return Column(
children: [
Expanded(
child: FortuneWheel(
physics: CircularPanPhysics(
duration: Duration(seconds: 1),
curve: Curves.decelerate,
),
onFling: () {
print('onFling');
selected.add(1);
},
onAnimationStart: () {
print('animation start');
},
onAnimationEnd: () {
print('animation end ${selected.stream}');
},
animateFirst: false,
selected: selected.stream,
items: [
for (var it in items) FortuneItem(child: Text(it)),
],
),
),
],
);
}
}
The print on onAnimationEnd only shows: animation end Instance of '_ControllerStream' but not the value. I am expect to get at least one of the item or the position of the item. Please help. Thanks!
Got it to work. Just need some changes.
Change your declaration of stream controller to broadcast
StreamController<int> _controller = StreamController.broadcast();
Then the trick. In some place of your widget tree (mine was just above the FortuneWheel in a Column) insert this StreamBuilder. This will show nothing, just handle some functions. In order to let us handle the snapshot result, we wil add the _text funciontion returning a widget. See bellow:
StreamBuilder(
stream: _controller.stream,
builder: (context, snapshot) => snapshot.hasData
? _text(snapshot)
: Container(),
)
And now, the function returning the widget _text.
Widget _text(var snapshot) {
//here you cand get and handle the result and do whathever.
print(snapshot.data);
int val = snapshot.data;
print(items[val]);
return Text(snapshot.data.toString()); //you dont need to return //anything here. Just replace the Text widget with SizedBox() to return //nothing.
}
As, the library is using Stream you will need to use stream method to get data from selection.One such method is called listen()
Rest you can check this : Medium Link - Streams In Flutter
var rendomval = Fortune.randomInt(0, items.length); setState(() { selected.add(rendomval); }); print(rendomval);
Declare the stream controller like this
StreamController<int> _controller = StreamController.broadcast();
then call the listen whatever you want , suggesting use listener inside initState function
_controller.stream.listen((value) {
print('Value from controller: $value');
})

type 'int' is not a subtype of type 'List<dynamic>'

I have a syncfusion chart. I want to fetch data from firebase. The data is 'int' type on yAxis. And the data for xAxis si just type 'datetime' and not fetch from anywhere. Can anybody help me? I just tired for trying this scince february and nothing happen with my chart. Thank you!
this is my code :
#override
Widget build(BuildContext context) {
return MaterialApp(debugShowCheckedModeBanner: false, home: LiveChart());
}
}
class LiveChart extends StatefulWidget {
#override
_LiveChartState createState() => _LiveChartState();
}
class _LiveChartState extends State<LiveChart> {
Timer timer;
int count = 0;
final dbRef = FirebaseDatabase.instance.reference();
List<_ChartData> chartData = <_ChartData>[];
Map<dynamic, dynamic> data = new Map();
void _updateDataSource(Timer timer) {
setState(() {
if (count >= 59) {
count = 0;
}
chartData.add(_ChartData(x: DateTime(2021, 1, 1, count), y1: data['y1']));
if (chartData.length == 20) {
chartData.removeAt(0);
}
count = count + 1;
});
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(body: _showChart());
}
Widget _showChart() {
return StreamBuilder(
stream: dbRef.child("Data").orderByChild('$count').onValue,
builder: (context, snapshot) {
Widget widget;
if (snapshot.hasData &&
!snapshot.hasError &&
snapshot.data.snapshot.value != null) {
List<dynamic> values = snapshot.data.snapshot.value["Moisture"];
if (values != null && count < values.length) {
data = values[count];
timer = Timer.periodic(
Duration(milliseconds: 1000), _updateDataSource);
}
widget = Container(
child: SfCartesianChart(
tooltipBehavior: TooltipBehavior(enable: true),
primaryXAxis: DateTimeAxis(),
series: <LineSeries<_ChartData, DateTime>>[
LineSeries<_ChartData, DateTime>(
dataSource: chartData,
xValueMapper: (_ChartData data, _) => data.x,
yValueMapper: (_ChartData data, _) => data.y1,
)
],
),
);
} else {
widget = Center(child: CircularProgressIndicator());
}
return widget;
});
}
#override
void dispose() {
super.dispose();
timer?.cancel();
}
}
class _ChartData {
_ChartData({this.x, this.y1});
final DateTime x;
final int y1;
}
and this is the error:
════════ Exception caught by widgets library ═══════════════════════════════════
The following _TypeError was thrown building StreamBuilder<Event>(dirty, state: _StreamBuilderBaseState<Event, AsyncSnapshot<Event>>#ec6fc):
type 'int' is not a subtype of type 'List<dynamic>'
It is difficult to completely understand the code without knowing the data that you are retrieving from Firebase. However, it looks like the offending line is:
List<dynamic> values = snapshot.data.snapshot.value["Moisture"];
Is this value truly a List or is it int which the error message implies?

Flutter Provider: How to notify a model that a change happened on a model it contains?

I'm starting to learn Flutter/Dart by building a simple Todo app using Provider, and I've run into a state management issue. To be clear, the code I've written works, but it seems... wrong. I can't find any examples that resemble my case enough for me to understand what the correct way to approach the issue is.
This is what the app looks like
It's a grocery list divided by sections ("Frozen", "Fruits and Veggies"). Every section has multiple items, and displays a "x of y completed" progress indicator. Every item "completes" when it is pressed.
TheGroceryItemModel looks like this:
class GroceryItemModel extends ChangeNotifier {
final String name;
bool _completed = false;
GroceryItemModel(this.name);
bool get completed => _completed;
void complete() {
_completed = true;
notifyListeners();
}
}
And I use it in the GroceryItem widget like so:
class GroceryItem extends StatelessWidget {
final GroceryItemModel model;
GroceryItem(this.model);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: model,
child: Consumer<GroceryItemModel>(builder: (context, groceryItem, child) {
return ListTile(
title: Text(groceryItem.name),
leading: groceryItem.completed ? Icon(Icons.check_circle, color: Colors.green) : Icon(Icons.radio_button_unchecked)
onTap: () => groceryItem.complete();
})
);
}
}
The next step I want is to include multiple items in a section, which tracks completeness based on how many items are completed.
The GroceryListSectionModel looks like this:
class GroceryListSectionModel extends ChangeNotifier {
final String name;
List<GroceryItemModel> items;
GroceryListSectionModel(this.name, [items]) {
this.items = items == null ? [] : items;
// THIS RIGHT HERE IS WHERE IT GETS WEIRD
items.forEach((item) {
item.addListener(notifyListeners);
});
// END WEIRD
}
int itemCount() => items.length;
int completedItemCount() => items.where((item) => item.completed).length;
}
And I use it in the GroceryListSection widget like so:
class GroceryListSection extends StatelessWidget {
final GroceryListSectionModel model;
final ValueChanged<bool> onChanged;
GroceryListSection(this.model, this.onChanged);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: model,
child: Consumer<GroceryListSectionModel>(
builder: (context, groceryListSection, child) {
return Container(
child: ExpansionTile(
title: Text(model.name),
subtitle: Text("${groceryListSection.completedItemCount()} of ${groceryListSection.itemCount()} completed"),
children: groceryListSection.items.map((groceryItemModel) =>
GroceryItem(groceryItemModel)).toList()
)
);
}
)
);
}
}
The Problems:
It seems weird to have a ChangeNotifierProvider and a Consumer in both Widgets. None of the examples I've seen do that.
It's definitely wrong to have the GroceryListSectionModel listening to changes on all the GroceryItemModels for changes to propagate back up the tree. I don't see how that can scale right.
Any suggestions? Thanks!
this ist not a nested Provider, but i think in your example it is the better way..
only one ChangeNotifierProvider per section ("Frozen", "Fruits and Veggies") is defined
the complete() function from a ItemModel is in the GroceryListSectionModel() and with the parameter from the current List Index
class GroceryListSection extends StatelessWidget {
final GroceryListSectionModel model;
// final ValueChanged<bool> onChanged;
GroceryListSection(this.model);
#override
Widget build(BuildContext context) {
return new ChangeNotifierProvider<GroceryListSectionModel>(
create: (context) => GroceryListSectionModel(model.name, model.items),
child: new Consumer<GroceryListSectionModel>(
builder: (context, groceryListSection, child) {
return Container(
child: ExpansionTile(
title: Text(model.name),
subtitle: Text("${groceryListSection.completedItemCount()} of ${groceryListSection.itemCount()} completed"),
children: groceryListSection.items.asMap().map((i, groceryItemModel) => MapEntry(i, GroceryItem(groceryItemModel, i))).values.toList()
)
);
}
)
);
}
}
class GroceryItem extends StatelessWidget {
final GroceryItemModel model;
final int index;
GroceryItem(this.model, this.index);
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(model.name),
leading: model.completed ? Icon(Icons.check_circle, color: Colors.green) : Icon(Icons.radio_button_unchecked),
onTap: () => Provider.of<GroceryListSectionModel>(context, listen: false).complete(index),
);
}
}
class GroceryListSectionModel extends ChangeNotifier {
String name;
List<GroceryItemModel> items;
GroceryListSectionModel(this.name, [items]) {
this.items = items == null ? [] : items;
}
int itemCount() => items.length;
int completedItemCount() => items.where((item) => item.completed).length;
// complete Void with index from List items
void complete(int index) {
this.items[index].completed = true;
notifyListeners();
}
}
// normal Model without ChangeNotifier
class GroceryItemModel {
final String name;
bool completed = false;
GroceryItemModel({this.name, completed}) {
this.completed = completed == null ? false : completed;
}
}