Use a List of an async function in another class - firebase

I’m basically creating a slideshow that contains texts from a list resulting from an async function.
This is the class that contains the homepage, async function and slideshow :
class HomePage extends StatefulWidget {
HomePage({Key key, this.auth, this.userId, this.logoutCallback, this.profile})
: super(key: key);
final Auth auth;
final VoidCallback logoutCallback;
final String userId;
final ProfilePage profile;
#override
State<StatefulWidget> createState() => new _HomePageState();
}
class HomePage extends StatefulWidget {
HomePage({Key key, this.auth, this.userId, this.logoutCallback, this.profile})
: super(key: key);
final Auth auth;
final VoidCallback logoutCallback;
final String userId;
final ProfilePage profile;
#override
State<StatefulWidget> createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
void initState() {
super.initState();
asyncMethod();
}
void asyncMethod() async {
await getMission1();
....
}
...
List<String> MissionData1 = [];
...
Future<void> getMission1() async{
DocumentSnapshot snap = await widget.auth.MissionRetriever1();
Map<String,dynamic> data = snap.data();
setState(() {
MissionData1.add(data['Q_Category']);
MissionData1.add(data['Q_Name']);
MissionData1.add(data['Q_Description']);
MissionData1.add(data['Q_Score']);
MissionData1.add(data['Q_Target']);
)};
...
Widget showTaskSlider() {
return new Column(
children:<Widget>[
CarouselSlider(options: CarouselOptions(height: 30.0.h, autoPlay: true, autoPlayInterval: Duration(seconds: 3), autoPlayAnimationDuration: Duration(milliseconds: 800), autoPlayCurve: Curves.fastOutSlowIn, aspectRatio: 2.0,
onPageChanged: (index, reason){setState(() {
_currentIndex= index;
});},
),
items: cardList.map((card){
return Builder(builder:(BuildContext context){
return Container(height: MediaQuery.of(context).size.height*0.30, width: MediaQuery.of(context).size.width,
child: Card(color:Colors.blueAccent, child: card,),
);
}
);
}).toList()
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(cardList, (index, url) {
return Container(
width: 3.0.w,
height: 5.0.h,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _currentIndex == index ? Colors.blueAccent : Colors.grey,
),
);
}),
),
],
);
}
}
and this is one of the classes of the slide
class Item1 extends StatelessWidget {
const Item1({Key key, this.homepage}) : super(key: key);
final _HomePageState homepage;
#override
Widget build(BuildContext context) {
return Container(
decoration: new BoxDecoration(image: DecorationImage(image: AssetImage("assets/illustrations/ill_1.jpeg"), fit: BoxFit.cover,),),
child: Column(
children: <Widget>[
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Row(children:[Image(image:AssetImage("assets/images/leaf.png"),width: 8.0.w,),Text(homepage.MissionData1 == null ? "Loading" : homepage.MissionData1[1], style:TextStyle(fontWeight: FontWeight.w500, fontFamily: 'Roboto',color: const Color(0xFFFFFFFF), fontSize: 15.0.sp),)]),Container(height: 20.0.h),Row(children: [Text("Dio Porco", style:TextStyle(fontWeight: FontWeight.w500, fontFamily: 'Roboto',color: const Color(0xFFFFFFFF), fontSize: 25.0.sp),)])],)), ]),
);
}
}
But when I start debugging it gives me this error
The following NoSuchMethodError was thrown building Item1(dirty):
The getter 'MissionData1' was called on null.
Receiver: null
Tried calling: MissionData1

Related

How to send to data or value from StatefulWidget subclass to StatelessWidget?

I want to add some data from Stateful subclass to Stateless main
These are codes I wrote.
I know if I use Stateless widget only, these code will work properly.
But I want to some function that use Stateful widget later.
main.dart
children: [
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(workout.title,
style: TextStyle(fontSize: 14)),
),
Padding(
padding: const EdgeInsets.only(top: 70),
child: Text(workout.count,
style: TextStyle(fontSize: 12)),
),
],
main_model.dart
Future add() async {
final collection = FirebaseFirestore.instance.collection('workoutlist');
await collection.add({
'title': newWorkoutText,
'count': int.parse(newWorkoutDigit),
'createdAt': Timestamp.now(),
});
add_page.dart
class AddPage extends StatefulWidget {
MainModel model;
final String newWorkoutText;
final String newWorkoutDigit;
AddPage({Key key,this.model,this.newWorkoutText, this.newWorkoutDigit}): super(key : key);
#override
_AddPage createState() => _AddPage();
}
class _AddPage extends State<AddPage> {
String newWorkoutText;
String newWorkoutDigit;
MainModel model;
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MainModel>.value(
value: model,
--------------------------------------------------------------------------
TextField(
keyboardType: TextInputType.number,
onChanged: (text) {
Text('{$widget.newWorkoutDigit}');
},
),

How i can pass Data from one widget to another widget in flutter?

I want to pass Data from one widget to another widget.
I'm getting data from firebase and I want the pass that data across the widgets.
How to pass Data from one screen to another screen.
this is how my code looks like.
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int _currentindex = 0;
final List<Widget> _children = [
Dashboard(),
Search(),
];
void onTappedBar(int index) {
setState(() {
_currentindex = index;
});
}
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<UserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
return return Scaffold(
backgroundColor: Color(0xFFf6f5fb),
body: _children[_currentindex],
bottomNavigationBar: CurvedNavigationBar(
onTap: onTappedBar,
index: _currentindex,
items: <Widget>[
Icon(
Icons.home,
),
Icon(
Icons.search,
],
),
);
});
}
}
From this widget, Data get loaded from firebase. Now I want pass snapshot.data to Dashboard() widget and Search() widget.
i want show the username Dashboard().
this how my ```Dashboard()`` Widget for exmaple
class Dashboard extends StatefulWidget {
#override
_DashboardState createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
#override
Widget build(BuildContext context) {
return Center(
child: Text('Here i want display the data')
),
);
}
}
Here is the model class:
class User {
final String uid;
User({this.uid});
}
class UserData {
final String uid;
final String username;
final String phonenumber;
UserData({ this.uid, this.username, this.phonenumber });
}
pass it through constructor if it is simple scenario like yours:
class Dashboard extends StatefulWidget {
final UserData userData;
// userData is not optional-named parameter
const Dashboard(this.userData, {Key key}) : super(key: key);
#override
_DashboardState createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
#override
Widget build(BuildContext context) {
final UserData userData = widget.userData;//do something with user
return Center(
child: Text('user is ${user.username}')
),
);
}
}
and the HomeState (don't save widgets as fields of the class, create them on the fly):
class _HomeState extends State<Home> {
int _currentindex = 0;
void onTappedBar(int index) {
setState(() {
_currentindex = index;
});
}
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<UserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
return Scaffold(
backgroundColor: Color(0xFFf6f5fb),
body: Column(
children: [
Dashboard(userData),
Search(userData),
],
),
bottomNavigationBar: CurvedNavigationBar(
onTap: onTappedBar,
index: _currentindex,
items: <Widget>[
Icon(
Icons.home,
),
Icon(
Icons.search,
],
),
);
});
}
}

I'm trying to pass on information that I get from one api e a component to another in flutter

I'm using a method of searching for an api but I'm not managing to pass the information I get to the Widget that renders it and get the data I all well
Header search Widget:
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:movies/Movies/bloc/blocmovies.dart';
import 'package:movies/Movies/model/findmoviemodel.dart';
import 'package:movies/Movies/ui/widgets/gridview_search_screen.dart';
class HeaderSearchScreen extends StatefulWidget with PreferredSizeWidget {
HeaderSearchScreen({Key key}) : super(key: key);
#override
_HeaderSearchScreenState createState() => _HeaderSearchScreenState();
#override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
class _HeaderSearchScreenState extends State<HeaderSearchScreen> {
BlocMovies blocMovies;
final TextEditingController _controller = TextEditingController();
Widget appBarTitle() {
return TextField(
onSubmitted: searchOperation,
autofocus: true,
controller: _controller,
style: TextStyle(
color: Colors.black,
),
decoration: InputDecoration(
suffix: IconButton(
icon: Icon(Icons.cancel),
onPressed: () {
Future.delayed(Duration(milliseconds: 50)).then((_) {
_controller.clear();
FocusScope.of(context).unfocus();
});
},
),
hintText: "Buscar",
hintStyle: TextStyle(color: Colors.grey.withOpacity(0.5))),
);
}
#override
Widget build(BuildContext context) {
blocMovies = BlocProvider.of(context);
return buildAppBar(context);
}
Widget buildAppBar(BuildContext context) {
return AppBar(
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: Colors.white,
centerTitle: true,
title: this.appBarTitle());
}
searchOperation(String searchText) {
blocMovies.findMovies(searchText)
.then((data){
if(data.results.length == 0){
print("no se encontro");
showDialog(
context: context,
child: AlertDialog(
title: const Text("No se encontro la pelicula"),
actions: [
FlatButton(
child: const Text("Ok"),
onPressed: () => Navigator.pop(context),
),
],
),
);
}else{
setState(() {
print(data.results);
GridViewSearchScreen(listsearchmovieOne: data.results);
});
}
})
.catchError((){
print("Hubo un error");
});
}
}
/*
blocMovies.findMovies(searchText)
.then((data){
if(data.results.length == 0){
print("no se encontro");
showDialog(
context: context,
child: AlertDialog(
title: const Text("No se encontro la pelicula"),
actions: [
FlatButton(
child: const Text("Ok"),
onPressed: () => Navigator.pop(context),
),
],
),
);
}else{
//Here trying pass datan and debug console a get snapshot
GridViewSearchScreen(listsearchmovieOne: data.results);
}
})
.catchError((){
print("Hubo un error");
});
GridViewSearch:
import 'package:animate_do/animate_do.dart';
import 'package:flutter/material.dart';
import 'package:movies/Movies/model/findmoviemodel.dart';
import 'package:movies/Movies/ui/widgets/cadsearchmovies.dart';
import 'package:movies/Widgets/Screen_Sizes/responsive_screens.dart';
class GridViewSearchScreen extends StatefulWidget {
List<Result> listsearchmovieOne;
double _crossAxisSpacing = 15, _mainAxisSpacing = 12, _aspectRatio = 1;
GridViewSearchScreen({Key key, this.listsearchmovieOne}) : super(key: key);
#override
_GridViewSearchScreenState createState() => _GridViewSearchScreenState(listsearchmovie: this.listsearchmovieOne );
}
class _GridViewSearchScreenState extends State<GridViewSearchScreen> {
List<Result> listsearchmovie;
_GridViewSearchScreenState({this.listsearchmovie});
#override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
double _pixeRatio = MediaQuery.of(context).devicePixelRatio;
bool small = ResponsiveWidget.isScreenSmall(screenWidth, _pixeRatio);
bool medium = ResponsiveWidget.isScreenMedium(screenWidth, _pixeRatio);
bool large = ResponsiveWidget.isScreenLarge(screenWidth, _pixeRatio);
return (listsearchmovie == null)
? Center(
child: Container(
child: Text("No hay peliculas que mostrar"),
))
: Container(
margin: EdgeInsets.only(top: screenHeight * 0.2),
child: GridView.builder(
itemCount: listsearchmovie.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (large) ? 4 : (medium) ? 2 : (small) ? 2 : 2,
crossAxisSpacing: widget._crossAxisSpacing,
mainAxisSpacing: widget._mainAxisSpacing,
childAspectRatio: (large)
? screenWidth / (screenHeight / 0.62)
: (medium)
? screenWidth / (screenHeight / 1.03)
: (small)
? screenWidth / (screenHeight / 1.03)
: screenWidth / (screenHeight / 1.03),
),
itemBuilder: (BuildContext context, int i) {
final movie = listsearchmovie[i];
print(movie.posterPath);
return FadeInLeft(
duration: Duration(milliseconds: 10 * i),
child: CardSearchinfoMovies(
movie: Result(
backdropPath: movie.backdropPath,
overview: movie.overview,
posterPath: movie.posterPath,
voteAverage: movie.voteAverage,
title: movie.title)),
);
}));
}
}
and on this screen is where together these two widgets
import 'package:flutter/material.dart';
import 'package:movies/Movies/ui/widgets/gridview_search_screen.dart';
import 'package:movies/Movies/ui/widgets/header_search_screen.dart';
class ScreenSearchMovies extends StatefulWidget {
#override
_ScreenSearchMoviesState createState() => _ScreenSearchMoviesState();
}
class _ScreenSearchMoviesState extends State<ScreenSearchMovies> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: HeaderSearchScreen(),
body: Stack(
children:<Widget>[
GridViewSearchScreen()
]
)
);
}
}
Any idea what might be going on already trying everything and I can't get the information displayed?
Try this way:
`....
....
class _GridViewSearchScreenState extends State<GridViewSearchScreen> {
List<Result> listsearchmovie = List<Result>();
_GridViewSearchScreenState({this.listsearchmovie});
.....
.....
`

The getter 'email' was called on null

I'm trying to make a chat between two people using Flutter and Firebase but I'm facing an error when I connect into my app using Firebase's signInWithEmailAndPassword, it tells me:
The getter 'email' was called on null. Receiver: null Tried calling:
email
And Flutter also tells me the error come from the MaterialApp widget from my main.dart which doesn't help me to find the error..
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:social/responsive/size_config.dart';
import 'settings.dart';
import 'home.dart';
final _firestore = Firestore.instance;
FirebaseUser loggedInUser;
class ActivityFeed extends StatefulWidget {
static const String id = 'activity_feed_screen';
#override
_ActivityFeedState createState() => _ActivityFeedState();
}
class _ActivityFeedState extends State<ActivityFeed> {
final _auth = FirebaseAuth.instance;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
}
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
UserInfo(),
FlatButton(
child: Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {
Navigator.pushNamed(context, Settings.id);
},
),
FlatButton(
child: Icon(
Icons.not_interested,
color: Colors.white,
),
onPressed: () {
_auth.signOut();
Navigator.pushNamed(context, Home.id);
},
),
],
),
),
)
],
),
);
}
}
class UserInfo extends StatefulWidget {
#override
_UserInfoState createState() => _UserInfoState();
}
class _UserInfoState extends State<UserInfo> {
String email = loggedInUser.email;
String username;
#override
void initState() {
super.initState();
getUsername();
}
void getUsername() async {
DocumentReference docRef = _firestore.collection('users').document(email);
docRef.get().then((snapshot) {
if (snapshot.exists) {
username = snapshot.data['username'];
}
});
}
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Column(
children: <Widget>[
Text(
'Welcome $username',
style: TextStyle(
fontFamily: 'Amatic',
fontSize: SizeConfig.safeBlockHorizontal * 10),
),
],
)
;
}
}
So basically what I am just trying to display 'Welcome' + the username, but it doesn't want,
my Firebase Database have one collection named 'users', where the document names are the email the user used when he created his account.
All the Register/Log-In process seems to work fine.
If someone has a clue of what is happening that would be awesome, thanks.
You initialize username as null. You can either check it on the widget tree
username != null ? Text(
'Welcome $username',
style: TextStyle(
fontFamily: 'Amatic',
fontSize: SizeConfig.safeBlockHorizontal * 10),
) : CircularProgressIndicator()
and set it via setState()
setState(() {
username = snapshot.data['username'];
});
Another solution is to change
String username;
to
String username = '';
You should use a state management method by the way. setState() is very primitive and you will end up having sphagetti code if you use it as a state management solution.

Multiple Containers interaction in single touch move

Playing around with Flutter, I am trying to interact in one touch move with multiple elements. However my gesture is triggered only in first Container.
Is there any way to do this using GestureDetector or Listener classes?
I mean, is there any better solution than set Listener on parent element and calculate if current touch pointer position is between coordinates of child elements I want to recognize touch event?
Here is an example of code to illustrate the issue I am dealing with.
Swiping horizontaly, I would like to select all TapBox elements in Row.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Swipe select',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Swipe select'),
);
}
}
class TapBox extends StatefulWidget {
TapBox({Key key, this.bgColor}) : super(key: key);
Color bgColor;
#override
_TapBoxState createState() => new _TapBoxState();
}
class _TapBoxState extends State<TapBox> {
#override
Widget build(BuildContext context) {
return new Padding(
padding: new EdgeInsets.only(left: 10.0, right: 10.0),
child: new GestureDetector(
onPanUpdate: ((e) {
this.setState(() {
widget.bgColor = Colors.blueAccent;
});
}),
onPanStart: ((e) {
this.setState(() {
widget.bgColor = Colors.blueAccent;
});
}),
child: new Container(
width: 50.0,
height: 200.0,
color: widget.bgColor,
),
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TapBox(bgColor: Colors.grey),
new TapBox(bgColor: Colors.grey),
new TapBox(bgColor: Colors.grey),
new TapBox(bgColor: Colors.grey),
new TapBox(bgColor: Colors.grey),
],
),
),
);
}
}

Resources