I have a question in coding with dart language. How to transform a Future to the normal List? In my program, I need the result from web to continue next step and I don't know how to do it. In my case, I need to return the value of variable "data" as a List.
class _MyAppState extends State<MyApp> {
static List getList() {
var url = "http://watcherman.cn/web/json.php";
var data;
HttpClient client = new HttpClient();
client.getUrl(Uri.parse(url))
.then((HttpClientRequest request) => request.close())
.then((HttpClientResponse response) {
response.transform(UTF8.decoder).listen((contents) {
String jsonContent = contents.toString();
data = JSON.decode(jsonContent);
});
});
return data;
}
}
But it seems like not execute the network part. The flutter code part seems can't accept a Future.
class _MyAppState extends State<MyApp> {
static List content = getList();
@override
Widget build(BuildContext context) {
return new Container(
child: new ListView.builder(
scrollDirection: Axis.vertical,
padding: new EdgeInsets.all(6.0),
itemCount: content.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
alignment: FractionalOffset.center,
margin: new EdgeInsets.only(bottom: 6.0),
padding: new EdgeInsets.all(6.0),
color: Colors.blueGrey,
child: new Text(content[index]["title"])
);
}
)
);
}
}
You should rewrite your getList
method to return a Future<List>
. It's possible to do this with a chain of then()
invocations, but far more readable IMO to use async
/await
.
Once you have a method that returns a Future<List>
, you can use FutureBuilder
to build a tree that depend on the results of the asynchronous computation.
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:async';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
State createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
static Future<List> getList() async {
var url = "http://watcherman.cn/web/json.php";
HttpClient client = new HttpClient();
HttpClientRequest request = await client.getUrl(Uri.parse(url));
HttpClientResponse response = await request.close();
return response.transform(UTF8.decoder).transform(JSON.decoder).toList();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Futures Demo'),
),
body: new FutureBuilder(
future: getList(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (!snapshot.hasData)
return new Container();
List content = snapshot.data[0];
return new ListView.builder(
scrollDirection: Axis.vertical,
padding: new EdgeInsets.all(6.0),
itemCount: content.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
alignment: FractionalOffset.center,
margin: new EdgeInsets.only(bottom: 6.0),
padding: new EdgeInsets.all(6.0),
color: Colors.blueGrey,
child: new Text('${content[index]['title']}'),
);
},
);
}
)
);
}
}
You cannot escape from being asynchronous.
In Dart, a function either returns a value or a Future
. It returns a future when the result isn't ready yet when the function returns, it will only be available at a later time.
That means that you are stuck if all you have is a Future
and you want the value right now, because the value just isn't there yet. You cannot return the List
now, because the Future<List>
doesn't have a list now, it only has it later.
So, you have to wait for that future, var data = await client.getUrl(...)...
, and that means that your function must be asynchronous too.
So, make the getList
function return a Future<List>
instead of a List
, because that's all it can do.
The alternative, which Dart doesn't support, would be a blocking operation that stops execution until a value is available, and then continues the normal execution. That's a problem in a single-threaded language (like Dart and JavaScript, which Dart must compile to) because blocking means nothing happens and the UI becoming unresponsive.
So, if your result depends on the value of a future, then your function must be asynchronous too and return its own result as a future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With