Search code examples
flutterdartasync-awaitfuturetask

Is there a way I can use Future values in Dart to fill Textfields?


I've been learning Dart with flutter and was creating Weather App for practices , I managed to successfully create the UI , I used Dark Sky weather API since it has 7 day weather forecast but instead of taking the long road of decoding json and models , I used Dark Sky Library. Here's the code for the API

Future<Null> getWeather() async {
Location location = Location();
await location.getCurrentPosition();
var darksky = DarkSkyWeather(
  MY_API_KEY,
  units: Units.SI,
  language: Language.English,
);
var forecast = await darksky.getForecast(
    location.latitude, location.longitude, excludes: [
    Exclude.Hourly,
    Exclude.Minutely,
    Exclude.Alerts,
    Exclude.Flags
    ]);
print(forecast.currently.temperature.round());
print(forecast.daily.data[0].temperatureMax);
 }

I wanted to use the forecast variable outside the functions and to fill the text fields such the humidity temperature among other data in the package . How can I access it ? any help will be appreciated . Thanks


Solution

  • Take a look at this code

    class _MyHomePageState extends State<MyHomePage> {
    
      String _data; // This holds the data to be shown
    
      @override
      void initState() {
        _data = "Press the button"; // This is the initial data // Set it in initState because you are using a stateful widget
        super.initState();
      }
    
      // Call this to set the new data
      void setData() {
        setState(() { // Remember to use setState() else the changes won't appear
          _data = 'Hello World';
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Message',
                ),
                Text(
                  '$_data', // See how the data is fed into this text widget
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: setData, // When I press the button, the new data is set
            child: Icon(Icons.send),
          ), 
        );
      }
    }
    

    Output:

    Initially:

    Initially

    After pressing the button:

    After pressing the button


    Do the same thing in your code.

    // Your code modified a bit
    // Make sure this is a stateful widget because you are changing values
    double _tempNow; // Declare two vars inside the class
    double _tempMax;
    
    // Your initState
    @override
    void initState() {
        _tempNow = 0; // Initial values
        _tempMax = 0;
        super.initState();
    }
    
    // Build method
    @override
    Widget build(BuildContext context) {
        // Your layout Code.....
             Text(
                  'Current: $_tempNow' // Here you set the tempNow
             ),
             ......
             Text(
                  'Maximum: $_tempMax' // and tempMax in the text widgets
             ),
        // End
    }
    
    Future<Null> getWeather() async {
        Location location = Location();
        await location.getCurrentPosition();
        var darksky = DarkSkyWeather(
            "8810b3633934b8c1975c51a2311dc1d0",
            units: Units.SI,
            language: Language.English,
        );
        var forecast = await darksky.getForecast(
            location.latitude, location.longitude, excludes: [
            Exclude.Hourly,
            Exclude.Minutely,
            Exclude.Alerts,
            Exclude.Flags
        ]);
    
        // Change the values here.
        // After the data is fetched, The changes will be made automatically
        setState(() {
            _tempNow = forecast.currently.temperature.round();
            _tempMax = forecast.daily.data[0].temperatureMax;
        });
     }
    

    In quite a similar manner, you can use text fields too. In that case, You will need to use TextEditingController and set the text there but, it seems in your case, you need read-only text to show the information to the user so a simple Text widget is enough