I'm trying to display the featured image from a Wordpress api using the following code:
home.dart:
class _PostTileState extends State<PostTile> {
#override
Widget build(BuildContext context) {
return Container(
child: Column(children: [
FutureBuilder(
future: fetchWpPostImageUrl(widget.href),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Image.network(snapshot.data["guid"]["rendered"]);
}
return CircularProgressIndicator();
},
),
Text(widget.title),
Text(widget.desc)
]));
}
}
wp-api.dart:
Future fetchWpPostImageUrl(href) async {
final response =
await http.get(href, headers: {"Accept": "application/json"});
var convertedDatatoJson = jsonDecode(response.body);
return convertedDatatoJson;
}
The code executes at the CircularProgressIndicator but does not display the image despite the map being correct.
I solved the issue:
Future fetchWpPostImageUrl(href) async {
final response =
await http.get(Uri.parse(href), headers: {"Accept": "application/json"});
var convertedDataJson = jsonDecode(response.body);
return convertedDataJson;
}
Related
I have a json file from where I am collecting only email addresses, and want to print index number base output like 3rd record's email address to Text widget..
class _HomeScreenState extends State<HomeScreen> {
List<String> list = [];
Future<List<String>> getcomments() async {
Uri url =
Uri.parse('https://jsonplaceholder.typicode.com/posts/1/comments');
var response = await http.get(url);
if (response.statusCode == 200) {
var jsondata = json.decode(response.body);
list.clear();
for (var jdata in jsondata) {
list.add(jdata['email']);
}
}
return list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('JSON'),
),
body: Center(
child: FutureBuilder(
future: getcomments(),
builder: (context, snapshot) {
return Text(snapshot.data[2].toString());
//here i want only 3rd data(index 2)
},
),
),
);
}
}
Can you try this?
FutureBuilder(
future: getcomments(),
builder: (context, snapshot) {
List<String> data = snapshot.data as List<String>;
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
else {
return Text(data[2]);
}
},
),
iam new to flutter and trying to fetch data from api for testing but i have some errors, here is the link that iam trying to fetch data from it and display it into FutureBuilder but i can't get to the information any one can help me !
here is my code:
class _MyHomePageState extends State<MyHomePage> {
final String apiUrl = "https://jsonplaceholder.typicode.com/users";
Future<List<Post>> fetchData() async {
http.Response res = await http.get(apiUrl);
if (res.statusCode == 200) {
var obj = json.decode(res.body);
List<Post> posts = new List<Post>();
for(int i=0;i>obj.length;i++){
Post post = Post.fromJson(obj[i]);
posts.add(post);
print(post.name);
}
return posts;
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
fetchData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: FutureBuilder(
future: fetchData(),
builder: (ctx,snapShot){
if(snapShot.connectionState == ConnectionState.waiting){
return CircularProgressIndicator();
}else{
return ListView.builder(
itemBuilder: (context,index){
return ListTile(
leading: CircleAvatar(),
title: Text(""),
subtitle: Text(""),
);
});
}
},
),
),
);
}
}
here is the link that i transform api json to dart
Change
for(int i=0;i>obj.length;i++){
Post post = Post.fromJson(obj[i]);
posts.add(post);
print(post.name);
}
return posts;
To
var response = List<Post>.from(obj.map((i) => Post.fromJson(i)));
return response;
After, add itemCount: snapShot.data.length into your ListView.builder
I have a strange problem. I need the value of a Future<String> as String to display an image with CachedNetworkImage. Because I have to wait for a downloadUrl which comes from Firebase Storage I found no way to use it as normal String.
Here is my Widget where I need the value
Container(child: Obx(
() {
return CachedNetworkImage(
imageUrl: _getImage(), // Here I need the value as String
height: Get.height,
fit: BoxFit.cover);
},
))
And this is my _getImage() function
Future<String> _getImage() async {
var url = return await MyStorage().getDownloadUrl(url);
return url;
}
The getDownloadUrl() only returns a String with the download url from Firebase Storage
Future<String> getDownloadUrl(ref) async {
final StorageReference storage = FirebaseStorage().ref().child(ref);
final url = await storage.getDownloadURL();
return url.toString();
}
Because I definitely have to wait for the getDownloadUrl() I have no chance to return the value as String. But I need it as String. Otherwise I get an error.
How would you solve this problem?
A FutureBuilder will build the UI depending on the state of the Future. All you have to do is check if it has the data, then build the image.
Future<String> myFutureString() async {
await Future.delayed(Duration(seconds: 1));
return 'Hello';
}
#override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: myFutureString(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Container(
child: Text(snapshot.data),
);
}
return CircularProgressIndicator();
},
);
}
I am trying to use FutureBuilder but its showing error of A build function returned null
My code
class _EventsState extends State<Events> {
#override
Future<List> doSomeAsyncStuff() async {
final storage = new FlutterSecureStorage();
String value = await storage.read(key: 'token');
print(value);
String url = 'http://sublimeapi.netcodesolution.com/api/NewsAndEvents/';
String token = value;
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
var eventData = json.decode(response.body);
print(eventData["Data"]);
List _events = eventData["Data"];
return _events;
}
#override
Widget build(BuildContext context) {
double statusBarHeight = MediaQuery
.of(context)
.padding
.top;
return Expanded(
child: FutureBuilder(
future: doSomeAsyncStuff(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
List<Widget> children;
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
print('working');
print(snapshot.data);
return Container(
child: Column(
children: <Widget>[
Text('working')
],
),
);
}
}
}),
);
}
As you can see in code I am fetching data from API and its working fine. In code i print the value of _events in setState its also printing the value like this
I/flutter (32627): [{Id: 38, Description: Two days Workshop on Prevention of Suicide organized for GPs of Thar., ImagePath: /journals/2e8a55f3-6612-4b23-a0ea-e91022c159a8.pdf, CreatedBy: 4447, CreatedOn: 2019-09-18T14:56:13.357, Active: false, Type: Events, Attachment: null, AttachmentType: Events}
I need to print the Description value of this data in future widget but don't know why its showing error
The Error says it clearly! It returned null.
So you have to return something! Do something like this,
Future<List> doSomeAsyncStuff() async {
final storage = new FlutterSecureStorage();
String value = await storage.read(key: 'token');
print(value);
String url = 'http://sublimeapi.netcodesolution.com/api/NewsAndEvents/';
String token = value;
final response = await http.get(url, headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
var eventData = json.decode(response.body);
print(eventData["Data"]);
List _events = eventData["Data"];
return _events;
}
and also, we missed another case here.
Scaffold(
appbar: AppBar(
title: const Text('Sample Future Builder'),
),
body: Expanded(
child: FutureBuilder(
future: doSomeAsyncStuff(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
print('working');
print(snapshot.data);
return Container(
child: Column(
children: <Widget>[
Text('working')
],
),
);
}
}
return Center(child: Text("Not Loaded Yet!!"),)
}
),
),
);
Hope that solves your issue!
Tip: Move all your widgets under Scaffold. It would be the best practice. Refer this
I have a Future function in my Provider Repository. However it is Future<bool> since I need async for http request.
Future<bool> hasCard() async {
String token = await getToken();
var body = jsonEncode({"token": token, "userID": user.getUserID()});
var res = await http.post((baseUrl + "/hasCard"), body: body, headers: {
"Accept": "application/json",
"content-type": "application/json"
});
print(res.toString());
if (res.statusCode == 200) {
this.paymentModel = PaymentModel.fromJson(json.decode(res.body));
return true;
}
return false;
}
And in my Widget I want to check this value:
Widget build(BuildContext context) {
var user = Provider.of<UserRepository>(context);
if(user.hasCard())
{
//do something
}
But I get an error message:
Conditions must have a static type of 'bool'.dart(non_bool_condition)
Since it is a Widget type I cannot use async here. What could be the way to solve this?
You can use a FutureBuilder, it will build the widget according to the future value, which will be null until the future is completed. Here is an example.
FutureBuilder(
future: hasCard(),
builder: (context, snapshot) {
if (snapshot.data == null)
return Container(
width: 20,
height: 20,
child: CircularProgressIndicator());
if (snapshot.data)
return Icon(
Icons.check,
color: Colors.green,
);
else
return Icon(
Icons.cancel,
color: Colors.red,
);
},
)
Well not only for a Future<bool> for any other future you can use the FutureBuilder where the future is what returns you the type of future and snapshot is the data recieved from it.
FutureBuilder(
future: hasCard(),
builder: (context, snapshot) {
if (snapshot.data != null){
print(snapshot.data)}
else{
print("returned data is null!")}
},
)
and I would suggest assigning a default value to your bool.
good luck!