Get the last value on future - flutter

Im doing a flutter app for currency exchange, on the call of the function to print the value, only get the last value for all
basically this only get the last value of getvalue and put for all of the values.
class BodyWidgetState extends State<BodyWidget> {
#override
Widget build(BuildContext context) {
return Scaffold (
appBar: AppBar(title: Text(moed)),
body: ListView(
children: <Widget> [
ListTile (
leading: CircleAvatar(
backgroundImage: AssetImage('assets/mxn.png'),
),
title: Text('MXN'),
),
getValue(moed,'MXN'),
ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('assets/eur.png'),
),
title: Text('EUR'),
),
getValue(moed,'EUR'),
Widget getValue (String b, String c){
return (
FutureBuilder<Quote> (
future : getQuote(b,c),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Center(
child: Column(
children: <Widget>[
SizedBox(height: 10),
Text(snapshot.data.coin.toString()),
],
));
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
}));}

Related

Save in variable and print in console user id of Firebase

I want to save in a variable the user's uid brought from Firebase to later make a query with MySql but it gives me an error, I Want print in console the variable too, my code is as follows
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Bienvenido')),
body: Container(
child: Column(
children: <Widget>[
BlocBuilder<AuthCubit, AuthState>(
buildWhen: (previous, current) => current is AuthSignedIn,
builder: (_, state) {
final authUser = (state as AuthSignedIn).user;
return Center(
child: Column(
children: [
Text('Usuario: ${authUser.uid}'),
SizedBox(
height: 16,
),
ElevatedButton(
onPressed: () => context.read<AuthCubit>().signOut(),
child: Text('Salir'))
],
),
);
}
),
],
),
),
);
The element type 'String' can't be assigned to the list type 'Widget'. is this line.
Text('Usuario: ${authUser.uid}'), usuario=authUser.uid;

The argument type 'Iterable<dynamic>' can't be assigned to the parameter type 'List<Gif>'

I was trying to use the Giphy API to start using APIs in flutter but I got this bug and I don’t know how to fix it.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder<Iterable>(
future: _listadoGifs,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView(
children: _listGifs(snapshot.data!),
);
} else if (snapshot.hasError) {
return Text("error");
}
return Center(
child: CircularProgressIndicator(),
);
},
),
);
}
I do not use a List because I use the following class:
List<Widget> _listGifs(List<Gif> data) {
List<Widget> gifs = [];
for (var gif in data) {
gifs.add(Card(
child: Column(
children: [
Image.network(gif.url.toString()),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(gif.name.toString()),
),
],
)));
}
return gifs;
}

FutureBuilder has empty snapshot despite Future returns proper data

I have FutureBuilder widget as Scaffold's body and I want to display a list of widgets when database returns required info but while database is properly returning data the FutureBuilder does not show any widgets(like CircularProgressIndicator or required List as it finishes its job). Code shown below:
Future<List<Widget>> getList() async{
List<Widget> list = [];
var db = dbMethods();
db.getConnection().then((conn) async {
await Future.delayed(const Duration(seconds: 1));
var result = await conn.query("select * from info", []);
for(var row in result) {
var item = BilbordItem(
firm: row[2],
constructionType: row[3],
demonstrationType: row[4],
lat: double.parse(row[5]),
long: double.parse(row[6]),
sizeX: double.parse(row[7]),
sizeY: double.parse(row[8]),
address: row[9],
positionRate: int.parse(row[10]),
colorsRate: int.parse(row[11]),
passabilityRate: int.parse(row[12]),
typeRate: int.parse(row[13])
);
print(item.address); //here i was checking if database fetch is working and it does print required info
list.add(item);
}
conn.close();
});
return list;
}
class _ListPage extends State<ListPage>{
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Список билбордов"),
centerTitle: true,
),
body: FutureBuilder(
future: getList(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if(snapshot.connectionState == ConnectionState.done){
if(snapshot.hasData && !snapshot.hasError){
return Center(
child: Column(
children: snapshot.data,
),
);
}
else if(snapshot.hasError){
return SingleChildScrollView(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Icons.error_outline, color: Colors.red,),
Text(snapshot.error.toString()),
],
),
),
);
}
}else {
return Center(child: CircularProgressIndicator());
}
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Text("Empty"),
],
),
);
},
),
);
}
}

Displaying main screen to old user and an info screen to a new user before the main screen

So I have a main screen that I want to display straight away to an old user of the app (Meaning token has been set) but to a new user, I want to display a column with some information etc. first and after the user presses the button it will open the main screen. However, the below code doesn't work as I wish (this doesn't change the view in any way). What would be the correct approach to this problem?
#override
Widget build(BuildContext context) {
return FutureBuilder<bool>(
future: getPrefs(),
builder: (context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData) {
if(token == null){
return Column(
verticalDirection: VerticalDirection.up,
children: [
ElevatedButton(
onPressed: (){
return mainScreen();
},
),
],
);
}
else{
return mainScreen();
}
} else {
return CircularProgressIndicator();
}
}
);
Widget mainScreen(){
return Scaffold(
appBar: AppBar(
title: Text('Feed planner',
style: TextStyle(fontSize: 17),
),
toolbarHeight: 50,
actions: [
IconButton(icon: icon, onPressed: _pushSettings),
],
),
body: Center(
child: Column(
children: [
Expanded(child: _buildGrid()),
]
)
)
);
}
Edit 1, after OP provided more info:
Make your homescreen widget like this:
Widget mainScreen(bool token){
return Scaffold(
appBar: AppBar(
title: Text('Feed planner',
style: TextStyle(fontSize: 17),
),
toolbarHeight: 50,
actions: [
IconButton(icon: icon, onPressed: _pushSettings),
],
),
body: Center(
child: Column(
children: [
token == null ? Text('Add your text or widget here for new users') : Container()
Expanded(child: _buildGrid()),
]
)
)
);
}
And your Future builder like this:
FutureBuilder<bool>(
future: getPrefs(),
builder: (context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData) {
return mainScreen(snapshot); //or the token you are getting
}
else {
return CircularProgressIndicator();
}
})
The problem is here:
ElevatedButton(
onPressed: (){
return mainScreen();
},
)
You should use:
ElevatedButton(
onPressed: (){
Navigator.pushNamed(context, '/mainScreen'); //or whatever the name of your home screen is in routes.
},
)

Type 'List<Widget>' is not a subtype of type 'Widget'

I have looked for similar answers and tried using their proposed solutions with no success. I am trying to build a ListView with data from the Firestore. Everytime I try to run it, it gives me a "Type 'List' is not a subtype of type 'Widget'".
Thank you in advance!
Here are the two blocks of code involved in the error:
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("exercises").snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text("There is no expense");
return new Scaffold(
backgroundColor: Colors.blue[100],
appBar: AppBar(
title: Text('Test'),
backgroundColor: Colors.blue[400],
elevation: 0.0,
),
body: Column(
children: <Widget>[
ListView(
shrinkWrap: true,
padding: EdgeInsets.all(0),
children: <Widget>[getExpenseItems(snapshot)]
)
],
),
);
});
}
getExpenseItems(AsyncSnapshot<QuerySnapshot> snapshot) {
return snapshot.data.documents.map<Widget>((doc) =>
new Container(
child: Card(
child: ListTile(
title: new Text(doc["nome"]),
subtitle: new Text(doc["link"])
),
),
)
).toList();
}
Spread the returned list of widgets from getExpenseItems(snapshot):
body: Column(
children: <Widget>[
ListView(
shrinkWrap: true,
padding: EdgeInsets.all(0),
children: <Widget>[...getExpenseItems(snapshot)]
)
],
),
//....