Noam
Noam

Reputation: 535

Get data from future function to text widget

I am trying to implement a Column with a Text:

Column(
        children: <Widget>[
        Text('data from future function')
      ],
    ), 

I can't get the data from initState() cause initState() it's only void If I get data directly from the function

Text(function)

I get

instance of function

The function:

Future<double> calculate(int index) async {
    LocData _getUser = await getLoc();
    double uLat = _getUser.latitude;
    double uLng = _getUser.latitude;
    double pLat = parks[data].loc.lat;
    double pLng = parks[data].loc.lng;


    double dis = await Geolocator()
        .distanceBetween(uLat , uLng, uLng , pLat );
    return dis ;
  }

Any idea what can i do to get this data from the function directly to the text wigdet?

Upvotes: 0

Views: 526

Answers (2)

CopsOnRoad
CopsOnRoad

Reputation: 267594

Here is the full working code.

class _InfoPageState extends State<InfoPage> {
  String _text = "";

  @override
  void initState() {
    super.initState();

    calculate(10).then((value) {
      setState(() {
        _text = value.toString();
      });
    });
  }

  Future<double> calculate(int index) async {
    LocData _getUser = await getLoc();
    double uLat = _getUser.latitude;
    double uLng = _getUser.latitude;
    double pLat = parks[data].loc.lat;
    double pLng = parks[data].loc.lng;

    double dis = await Geolocator().distanceBetween(uLat, userLng, uLng, pLat);
    return dis;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(children: <Widget>[Text(_text)]),
    );
  }
}

Upvotes: 2

Daniel V.
Daniel V.

Reputation: 1198

There 2 ways to get data from a future.

Option #1:

(with 2 suboptions)

class MyWidgetState extends State<MyWidget> {

  String _someAsyncData;

  @override
  void initState() {
    super.initState();

    // opt 1.
    aDataFuture.then((val) {  
      setState(() {
        _someAsyncdata = val;
      });
    });      

    // opt 2.
    _setAsyncData(aDataFuture);
  }

  void _setAsyncData(Future<String> someFuture) async {
    // void + async is considered a "fire and forget" call
    // part of opt. 2
    _someAsyncData = await someFuture;
    // must trigger rebuild with setState
    setState((){});
  }


  Widget build(BuildContext context) {
    return _someAsyncData == null ? Container() : Text('$_someAsyncData');
  }
}

Option #2

Use FutureBuilder

class MyWidget extends StatelessWidget {

  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: _someFuture,
      builder: (ctx, snapshot) {
        // can also check for snapshot.hasData or snapshot.hasError to
        // provide more user feedback eg.
        if(snapshot.connectionState == ConnectionState.done) 
          return Text('${snapshot.data}');        
        return Text('No data available yet...');
      }
    );
  }

}

Upvotes: 3

Related Questions