unable to pass instance to the initializer [duplicate] - flutter

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));
}

Related

Could not find the correct Provider<Movies> above this MyApp Widget

So, I'm using BLoC and Provider packages in one app.
In my 'moviesprovider.dart' I am fetching some data from my API which returns a json, when app is opening first time. How can I get access to Provider.of(context) from main.dart in MultiProvider? Basically, I want to get access to the same instance of List movies, but don't know how.
The error I'm getting:
Error: Could not find the correct Provider above this MyApp Widget
This happens because you used a BuildContext that does not include the provider
of your choice.
Code:
Main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Movies(),
),
Provider<SwipeBloc>(create: (_) {
SwipeBloc()
..add(
LoadMoviesEvent(
movies: context.read<Movies>().movies,
),
);
}),
ChangeNotifierProvider.value(
value: User(),
),
ChangeNotifierProvider.value(
value: Auth(),
),
],
child: ...
}
}
movies_provider.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:movies_recomendations/constants.dart';
import 'package:http/http.dart' as http;
import './single_movie_provider.dart';
class Movies with ChangeNotifier {
String plotText = "";
List<Movie> _movies = [];
List<Movie> get movies {
return <Movie>[..._movies];
}
.....
Future<void> fetchAndSetMovies() async {
const url = 'http://192.168.1.142:8000/Desktop/textData.json';
try {
final response = await http.get(
Uri.parse(url),
);
String source = Utf8Decoder().convert(response.bodyBytes);
final extractedData =
List<Map<String, dynamic>>.from(json.decode(source));
final List<Movie> loadedMovies = [];
extractedData.forEach(
((movieInfo) => {
loadedMovies.add(Movie(
id: movieInfo['id'],
age: 12,
countries: List<String>.from(movieInfo['country']),
description: movieInfo['descriprion'],
frames: movieInfo['frames'],
genre: movieInfo['genre'],
poster: movieInfo['poster'],
premiereWorld: movieInfo['date'].toString(),
ratingIMDb: movieInfo['ratingIMDb'],
ratingKinopoisk: movieInfo['ratingKinopoisk'],
title: movieInfo['title'][1],
ifSeries: movieInfo['ifSeries'],
dateTo: movieInfo['dateTo'].toString(),
isFavourite: true,
seasons: movieInfo['seasons'],
)),
}),
);
_movies = loadedMovies;
notifyListeners();
} on Exception catch (e) {
print('error');
print(e.toString());
}
}
}
Swipe_event.dart
part of 'swipe_block.dart';
abstract class SwipeEvent extends Equatable {
const SwipeEvent();
#override
List<Object> get props => [];
}
class LoadMoviesEvent extends SwipeEvent {
final List<Movie> movies ;
LoadMoviesEvent({
required this.movies,
});
#override
List<Object> get props => [movies];
}
class SwipeLeftEvent extends SwipeEvent {
final Movie movie;
SwipeLeftEvent({
required this.movie,
});
#override
List<Object> get props => [movie];
}
class SwipeRightEvent extends SwipeEvent {
final Movie movie;
SwipeRightEvent({
required this.movie,
});
#override
List<Object> get props => [movie];
}
You probably need to move the code calling Provider.of(context) into its own widget. As the error implies you can't use Provider to retrieve dependencies within the same BuildContext you used to set the Provider scope. Creating a new widget will also generate a new BuildContext.
If you really need to use Provider.of(context) in the same class you define MultiProvider you could use the Builder widget to generate a new context.
So, to solve this problem you should NOT use BlocProvider in main.dart. You should use it in that direct widget where BLoC Provider will be implemented. So I use it in one screen - recomendations, so I write it there like this
class RecomendationsScreen extends StatelessWidget {
static const routeName = '/recomendations';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kBackgroundColor,
body: BlocProvider(
create: (_) => SwipeBloc()
..add(
LoadMoviesEvent(
movies: Provider.of<Movies>(context).movies,
),
),
child: RecomendationsBody(),
),
);
}
}

Class 'int' has no instance getter 'millisecondsSinceEpoch'

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

issue with flutter concatenation

I have a problem concatenating two variables on flutter : I can't concatenate them, when I try to add a string behind, it doesn't work.
class MusicAlbumListing extends StatefulWidget {
final albumName;
MusicAlbumListing({Key key, this.albumName}) : super(key: key);
#override
_MusicAlbumListing createState() => _MusicAlbumListing();
}
class _MusicAlbumListing extends State<MusicAlbumListing> {
String _albumName = '';
void initState() {
_albumName = widget.albumName.toString();
var strr = "Look this new album : $_albumName ! Awesome :)";
}
It returns
Look this new album : Mothership
And then nothing
Can anyone help me ?
I don't think there is anything wrong with your String concatenation.
Here is a Minimal Working Example based on your incomplete code snippet:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'StackOverflow Answer',
home: MusicAlbumListing(albumName: 'Mothership'),
);
}
}
class MusicAlbumListing extends StatefulWidget {
final String albumName;
MusicAlbumListing({Key? key, required this.albumName}) : super(key: key);
#override
_MusicAlbumListing createState() => _MusicAlbumListing();
}
class _MusicAlbumListing extends State<MusicAlbumListing> {
String _albumName = '';
void initState() {
super.initState();
_albumName = "Look this new album : ${widget.albumName} ! Awesome :)";
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text(_albumName)),
);
}
}
Provide your Minimal Working Example for a more targeted answer.
Thanks for your fast reply
First i fetch on a local server (my raspberry pi) a file called output.txt with ssh script
import 'package:flutter/material.dart';
import 'package:ssh/ssh.dart';
import 'album_music.dart';
class MainMenu extends StatefulWidget {
#override
_MainMenu createState() => _MainMenu();
}
class _MainMenu extends State<MainMenu> {
String _result = '';
List _array;
final pi = new SSHClient(
host: "192.168.0.35",
port: 22,
username: "pi",
passwordOrKey: "mysecret",
);
Future<void> exec(String sshScript) async {
String result;
try {
result = await pi.connect();
if (result == "session_connected") {
result = await pi.execute(sshScript);
pi.disconnect();
}
} catch (e) {
print('Error: ${e.code}\nError Message: ${e.message}');
}
setState(() {
_result = result;
_array = null;
});
}
#override
void initState() {
super.initState();
exec(
"cd ../../; cd var/www/html/music; ls -d */ > output.txt; cat output.txt");
}
#override
Widget build(BuildContext context) {
final title = 'Albums disponibles';
var strings = _result.split('\n');
print(strings);
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView(
children: new List.generate(
strings.length - 1,
(index) => new ListTile(
title: Text(strings[index],
style: TextStyle(fontWeight: FontWeight.w500)),
leading: Icon(Icons.folder_open),
trailing: Icon(Icons.forward),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MusicAlbumListing(
albumName: strings[index].replaceAll("/", ""))));
},
),
)),
),
);
}
I open the txt file, and transform the cat output.txt to an array.
I think you're right, maybe the problem is not the concatenation.
For the first loop, Daft_Punk goes well.
That's my txt file :
Daft_Punk
MotherShip
LeonardCohenBestSongs
Pink_Floyd_Essentials
I have : Look this new album : Daft_Punk ! Awesome :)
But second loop and those after, concatenation won't work
Maybe a "bad" character has been introduced, which prevents concatenation

Flutter, how to pass a parameter to constructor

this is my code, i dont know how to pass this listOfTiles to my StatefulWidget, can u help me and describe how it works?
body: new ListView.builder(
itemBuilder: (BuildContext context, int index) {
return new StuffInTilesState(listOfTiles[index]);//i want to pass this
},
itemCount: listOfTiles.length,
),
),
);
}
}
class StuffInTiles extends StatefulWidget{
#override
StuffInTilesState createState() => StuffInTilesState();//i know i need to change this, but i dont know how
}
class StuffInTilesState extends State<StuffInTiles> {
final MyTile myTile;
StuffInTilesState(this.myTile);//this is constructor, shuld this also be changed?
final _controller = TextEditingController();
String name = "";
If u want to see my working code: https://pastebin.pl/view/c4dbc2af If u want to see my not working code: https://pastebin.pl/view/83f9cad0 (https://codeshare.io/GLLm66)
You need to use the widget class constructor and not the state class.
You can access the values ​​in the state class with widget.YouProperty
class StuffInTiles extends StatefulWidget {
final MyTile myTile;
const StuffInTiles(this.myTile);
#override
_StuffInTilesState createState() => _StuffInTilesState();
}
class _StuffInTilesState extends State<StuffInTiles> {
#override
Widget build(BuildContext context) {
return Container(child:
Text(widget.myTile),);
}
}

MappedListIterable is not a SubType

I'm new to flutter and dart and trying to fetch data from firestore as a stream and feed to my ListView but I keep getting this error:
type 'MappedListIterable<DocumentSnapshot, Product>' is not a subtype
of type 'List<Product>'
I have seen a couple of other posts on stackoverflow like this but they either do not help me or do not apply to my situation.
This is my products page widget:
import 'package:xxx/models/Product.dart';
import 'package:agrogator/screens/products/widgets/products_list.dart';
import 'package:xxx/services/product.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProductsScreen extends StatelessWidget {
ProductsScreen({Key key}) : super(key: key);
final product = ProductService();
// This widget is the productsucts page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
#override
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return StreamProvider<List<Product>>.value(
value: product.streamProducts(),
child: new Scaffold(
appBar: new AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: new Text("xxx"),
),
body: new ProductsList(),
floatingActionButton: new FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
This is my ProductsList widget:
import 'package:xxx/models/Product.dart';
import 'package:xxx/screens/products/widgets/product_item.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProductsList extends StatelessWidget {
#override
Widget build(BuildContext context) {
var products = Provider.of<List<Product>>(context);
return Container(
height: 100,
child: ListView(
children: products.map((product) {
return new ProductItem(product: product);
}).toList(),
),
);
}
}
This is my ProductItem widget:
import 'package:xxx/models/Product.dart';
import 'package:flutter/material.dart';
class ProductItem extends StatelessWidget {
final Product product;
ProductItem({this.product});
#override
Widget build(BuildContext context) {
return Text(product.name, style: TextStyle(color: Colors.black));
}
}
This is my Product Model:
import 'package:cloud_firestore/cloud_firestore.dart';
class Product {
String uid;
String name;
String unit;
int avgQuantity;
double avgWeight;
double previousAvgPrice;
double currentAvgPrice;
String lastUpdatedBy;
String lastUpdatedAt;
String remarks;
Product(
{this.uid,
this.name,
this.unit,
this.avgQuantity,
this.avgWeight,
this.previousAvgPrice,
this.currentAvgPrice,
this.lastUpdatedBy,
this.lastUpdatedAt,
this.remarks});
factory Product.fromFirestore(DocumentSnapshot doc) {
Map data = doc.data;
return Product(
uid: doc.documentID,
name: data["name"],
unit: data["unit"],
avgQuantity: data["avgQuantity"],
avgWeight: data["avgWeight"],
previousAvgPrice: data["previousAvgPrice"],
currentAvgPrice: data["ccurrentAvgPrice"],
lastUpdatedBy: data["lastUpdatedBy"],
lastUpdatedAt: data["lastUpdatedAt"],
remarks: data["remarks"]);
}
}
And my service:
import 'package:xxx/models/Product.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ProductService {
final Firestore _db = Firestore.instance;
Stream<List<Product>> streamProducts() {
var ref = _db.collection("products");
return ref
.snapshots()
.map((list) => list.documents.map((doc) => Product.fromFirestore(doc)));
}
}
In your Service add .toList()
Like this below
import 'package:xxx/models/Product.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ProductService {
final Firestore _db = Firestore.instance;
Stream<List<Product>> streamProducts() {
var ref = _db.collection("products");
return ref
.snapshots()
.map((list) => list.documents.map((doc) => Product.fromFirestore(doc))).toList(); // <= here
}
}
You can try this. Hope this helps
Product Model
class Product {
String uid;
String name;
String unit;
int avgQuantity;
double avgWeight;
double previousAvgPrice;
double currentAvgPrice;
String lastUpdatedBy;
String lastUpdatedAt;
String remarks;
Product({this.uid,
this.name,
this.unit,
this.avgQuantity,
this.avgWeight,
this.previousAvgPrice,
this.currentAvgPrice,
this.lastUpdatedBy,
this.lastUpdatedAt,
this.remarks});
}
Product Service
class ProductService {
Stream<List<Product>> streamProducts() {
return _FirestoreStream<List<Product>>(
apiPath: "products",
parser: FirestoreProductsParser(),
).stream;
}
}
abstract class FirestoreNodeParser<T> {
T parse(QuerySnapshot querySnapshot);
}
class FirestoreProductsParser extends FirestoreNodeParser<List<Product>> {
List<Product> parse(QuerySnapshot querySnapshot) {
var products = querySnapshot.documents.map((documentSnapshot) {
return Product(
uid: doc.documentID,
name: data["name"],
unit: data["unit"],
avgQuantity: data["avgQuantity"],
avgWeight: data["avgWeight"],
previousAvgPrice: data["previousAvgPrice"],
currentAvgPrice: data["ccurrentAvgPrice"],
lastUpdatedBy: data["lastUpdatedBy"],
lastUpdatedAt: data["lastUpdatedAt"],
remarks: data["remarks"]
);
}).toList();
products.sort((lhs, rhs) => rhs.uid.compareTo(lhs.uid));
return products;
}
}
class _FirestoreStream<T> {
_FirestoreStream({String apiPath, FirestoreNodeParser<T> parser}) {
CollectionReference collectionReference = Firestore.instance.collection(apiPath);
Stream<QuerySnapshot> snapshots = collectionReference.snapshots();
stream = snapshots.map((snapshot) => parser.parse(snapshot));
}
Stream<T> stream;
}