Reputation: 427
i would love to call the Future fetchPost from a RaisedButton or in other words i don't wan't the FutureBuilder to do anything until i click the button, i tried calling fetchPost from the button but it won't work and I'm stuck.
PS: I used the example from this page https://flutter.io/cookbook/networking/fetch-data/
Your help is appreciated.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({this.userId, this.id, this.title, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
class FirstFragment extends StatelessWidget {
FirstFragment(this.usertype,this.username);
final String usertype;
final String username;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final Size screenSize = MediaQuery.of(context).size;
return new SingleChildScrollView(
padding: new EdgeInsets.all(5.0),
child: new Padding(
padding: new EdgeInsets.symmetric(vertical: 0.0, horizontal: 0.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
child: new RaisedButton(
child: new Text('Call'),
onPressed: (){
fetchPost();
},
),
),
new Container(
child: FutureBuilder<Post>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
)
)
],
),
),
);
}
}
Upvotes: 1
Views: 4198
Reputation: 1160
As Dhiraj explained above calling fetchPost alone won't change UI, so you need to reset UI by calling setState.
Below is how your code should look like
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({this.userId, this.id, this.title, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
class FirstFragment extends StatefulWidget {
FirstFragment(this.usertype,this.username);
final String usertype;
final String username;
@override
_FirstFragmentState createState() => new _FirstFragmentState(usertype, username);
}
class _FirstFragmentState extends State<FirstFragment> {
_FirstFragmentState(this.usertype,this.username);
final String usertype;
final String username;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final Size screenSize = MediaQuery.of(context).size;
return new SingleChildScrollView(
padding: new EdgeInsets.all(5.0),
child: new Padding(
padding: new EdgeInsets.symmetric(vertical: 0.0, horizontal: 0.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
child: new RaisedButton(
child: new Text('Call'),
onPressed: (){
fetchPost();
setState(() {
});
},
),
),
new Container(
child: FutureBuilder<Post>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
)
)
],
),
),
);
}
}
Upvotes: 2
Reputation: 4859
Calling fetchPost alone wont do changes in UI.
At first inside build your futurebuilder is execcuted which gets data from fetchPost.
Further then to fetchPost agiain you need to rebuild.
To do so inside onPressed of raised button:
onPressed: (){
setState((){})
},
And to fetch post only on button click (not for first time) you should use then()
Details here : https://www.dartlang.org/tutorials/language/futures
Upvotes: 2